通过Spring Websocket在连接时向客户端发送消息

5

好的,我已经阅读了关于Spring WebSocket的几乎所有stackoverflow帖子。

我想在特定客户端连接到服务器后发送一条消息,很简单!

我已经能够从客户端连接,并且可以在服务器端侦听新连接。但是当我尝试从服务器端发送消息时,什么也没有发生。即使我的客户端已经订阅了。

以下是我的客户端js代码。

var stompClient = null;
$(document).ready(function() {
    connect();
});

function connect() {
var socket = new SockJS('/context_path/stockfeeds');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
    console.log('Connected: ' + frame);
    stompClient.subscribe('/topic/share', function(message) {
        console.log("Subscription successful............");
        console.log(JSON.parse(message.body));
    });

    stompClient.subscribe('/user/queue/reply', function(message) {
        console.log("Subscribed to user ...");
    });
}, function (error) {
    console.log("Stomp protocol error: "+ error);
});
}

$('#livetext').click(function () {
    stompClient.send('/app/stockfeeds', {}, 'This is BS');
});

当我点击“#livetext”时,发送函数会起作用,并且客户端会收到响应。以下是我的控制器。

@Controller
public class StockDispatchController {

    @Autowired
    LoggerService loggerService;

    @MessageMapping("/stockfeeds")
    @SendTo("/topic/share")
    public String fetchStocks(String message) throws Exception {
        loggerService.info("-----------------------------"+ message);

        return message;
    }

}

以下是我的Connect事件监听器。
import org.springframework.messaging.simp.SimpMessagingTemplate;

@Component
public class StompConnectEvent implements ApplicationListener<SessionConnectEvent> {

@Autowired
LoggerService logger;

@Autowired
private SimpMessagingTemplate messagingTemplate;

public void onApplicationEvent(SessionConnectEvent event) {

    this.messagingTemplate.convertAndSend("/topic/share", "A new client just connected");
    this.messagingTemplate.convertAndSendToUser(event.getUser().getName(), "/queue/reply", "I just connected");
    logger.info("message template sent");
}

}

当一个新客户端连接时,事件监听器会被触发并运行到结束,但我在客户端上没有收到任何响应。
最后,以下是我的应用程序上下文xml。
<websocket:message-broker application-destination-prefix="/app">
    <websocket:stomp-endpoint path="/stockfeeds">
        <websocket:handshake-interceptors>
            <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
        </websocket:handshake-interceptors>
        <websocket:sockjs/>
    </websocket:stomp-endpoint>
    <websocket:simple-broker prefix="/topic, /queue"/>
</websocket:message-broker>
3个回答

4

我还没有找到解决方案,但我找到了一个可行的替代方案。因此,我添加了一个控制器方法,当用户订阅它时会触发该方法,而不是侦听SessionConnectedEvent事件。

如下所示。

@SubscribeMapping("/reply")
public String initialReply() throws Exception {
    return "Welcome to the chat room.";
}

我按照以下方式进行订阅。

stompClient.subscribe('/app/reply', function(message) {
    alert(message.body);
});

2

这里已经很晚了,但是以防有人需要。我使用了SessionSubscribeEvent而不是SessionConnectEvent,在阅读文档后它起作用了。

@Component
public class StompConnectEvent implements ApplicationListener<SessionSubscribeEvent> {

@Autowired
private SimpMessagingTemplate messagingTemplate;

public void onApplicationEvent(SessionSubscribeEvent event) {

    this.messagingTemplate.convertAndSend("/topic/share", messageObject);

    }
}

当客户端订阅Websocket终点时,将调用 SessionSubscribeEvent ,因此它可以接收服务器发送到终点的消息。但是,在客户端最初尝试连接Websocket时,将调用 SessionConnectEvent ,因此客户端尚未侦听终点。


0

我有类似的用例,这是我成功实现的方法。

  1. 您可以在客户端创建一些随机字符串,例如clientId23,然后通过已建立的websocket将其发送到服务器。
  2. 在订阅URL中添加相同的随机字符串,例如/app/reply/clientId23
  3. 在服务器端,您可以将该clientId持久化在数据库或其他地方,使用它可以向特定的客户端发送消息,例如this.messagingTemplate.convertAndSend("/app/reply/clientId23", "A new client just connected");

祝编码愉快!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接