通过 Spring Websocket 在连接时向客户端发送消息
Send message to client on connect via Spring Websocket
好的,我实际上已经阅读了 spring websocket 上的每一个 stackoveflow post。
我想在连接到服务器后向特定客户端发送消息,很简单!
我已经可以从客户端连接,我可以在服务器端监听新的连接。但是当我尝试从服务器端发送消息时,什么也没有发生。尽管我的客户已经订阅了。
下面是我的客户端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;
}
}
下面是我的连接事件监听器
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>
我还没有找到解决方案,但我找到了一个可行的替代方案。因此,我没有监听 SessionConnectedEvent,而是添加了一个控制器方法,该方法会在用户订阅时触发。
见下文。
@SubscribeMapping("/reply")
public String initialReply() throws Exception {
return "Welcome to the chat room.";
}
我订阅如下。
stompClient.subscribe('/app/reply', function(message) {
alert(message.body);
});
我有类似的用例,这就是我成功实施的。
- 您可以在客户端创建一些随机字符串,例如
clientId23
,您可以通过已建立的 websocket 将其发送到服务器。
- 在订阅中添加相同的随机字符串 URL 例如
/app/reply/clientId23
。
- 在服务器端,您可以将该 clientId 保存在数据库或其他东西中。您可以使用它向特定客户端发送消息,例如
this.messagingTemplate.convertAndSend("/app/reply/clientId23", "A new client just connected");
编码愉快!
这里已经很晚了,但以防万一有人可能需要这个。我没有使用对我不起作用的 SessionConnectEvent
,而是在阅读文档后使用 SessionSubscribeEvent
并且它起作用了。
@Component
public class StompConnectEvent implements ApplicationListener<SessionSubscribeEvent> {
@Autowired
private SimpMessagingTemplate messagingTemplate;
public void onApplicationEvent(SessionSubscribeEvent event) {
this.messagingTemplate.convertAndSend("/topic/share", messageObject);
}
}
一旦客户端订阅了 websocket 端点,就会调用 SessionSubscribeEvent
,因此它可以接收服务器发送到端点的消息。但是 SessionConnectEvent
在客户端最初尝试连接 websocket 时被调用,因此客户端还没有监听端点。
好的,我实际上已经阅读了 spring websocket 上的每一个 stackoveflow post。 我想在连接到服务器后向特定客户端发送消息,很简单!
我已经可以从客户端连接,我可以在服务器端监听新的连接。但是当我尝试从服务器端发送消息时,什么也没有发生。尽管我的客户已经订阅了。
下面是我的客户端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;
}
}
下面是我的连接事件监听器
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>
我还没有找到解决方案,但我找到了一个可行的替代方案。因此,我没有监听 SessionConnectedEvent,而是添加了一个控制器方法,该方法会在用户订阅时触发。
见下文。
@SubscribeMapping("/reply")
public String initialReply() throws Exception {
return "Welcome to the chat room.";
}
我订阅如下。
stompClient.subscribe('/app/reply', function(message) {
alert(message.body);
});
我有类似的用例,这就是我成功实施的。
- 您可以在客户端创建一些随机字符串,例如
clientId23
,您可以通过已建立的 websocket 将其发送到服务器。 - 在订阅中添加相同的随机字符串 URL 例如
/app/reply/clientId23
。 - 在服务器端,您可以将该 clientId 保存在数据库或其他东西中。您可以使用它向特定客户端发送消息,例如
this.messagingTemplate.convertAndSend("/app/reply/clientId23", "A new client just connected");
编码愉快!
这里已经很晚了,但以防万一有人可能需要这个。我没有使用对我不起作用的 SessionConnectEvent
,而是在阅读文档后使用 SessionSubscribeEvent
并且它起作用了。
@Component
public class StompConnectEvent implements ApplicationListener<SessionSubscribeEvent> {
@Autowired
private SimpMessagingTemplate messagingTemplate;
public void onApplicationEvent(SessionSubscribeEvent event) {
this.messagingTemplate.convertAndSend("/topic/share", messageObject);
}
}
一旦客户端订阅了 websocket 端点,就会调用 SessionSubscribeEvent
,因此它可以接收服务器发送到端点的消息。但是 SessionConnectEvent
在客户端最初尝试连接 websocket 时被调用,因此客户端还没有监听端点。