文档章节

spring websocket + stomp 实现广播通信和一对一通信<转>

王福林
 王福林
发布于 2017/03/28 13:48
字数 887
阅读 94
收藏 3

spring对于基于stomp协议的websocket通信,其官网上面有一个guide,但是根据guide你只能写出来广播方式的通信,不能实现一对一的通信,这篇文章在这里把广播和一对一一起整理一下给大家。

服务端:

一,依赖,spring-websocket和spring-messaging,这里给出maven方式:

 

  1. <dependency>  
  2.             <groupId>org.springframework</groupId>  
  3.             <artifactId>spring-websocket</artifactId>  
  4.             <version>${spring-core.version}</version>  
  5.         </dependency>  
  6.         <dependency>  
  7.             <groupId>org.springframework</groupId>  
  8.             <artifactId>spring-messaging</artifactId>  
  9.             <version>${spring-core.version}</version>  
  10.         </dependency>  


二,服务端代码:

 

服务端的初始化,只需要两个类:WebsocketConfig和WebSocketController

 

  1. import org.springframework.context.annotation.Configuration;  
  2. import org.springframework.messaging.simp.config.MessageBrokerRegistry;  
  3. import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;  
  4. import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;  
  5. import org.springframework.web.socket.config.annotation.StompEndpointRegistry;  
  6.   
  7. @Configuration  
  8. @EnableWebSocketMessageBroker  
  9. public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {  
  10.   
  11.     @Override  
  12.     public void configureMessageBroker(MessageBrokerRegistry config) {  
  13.         config.enableSimpleBroker("/topic","/user");  
  14.         config.setApplicationDestinationPrefixes("/app");  
  15.         config.setUserDestinationPrefix("/user/");  
  16.     }  
  17.   
  18.     @Override  
  19.     public void registerStompEndpoints(StompEndpointRegistry registry) {  
  20.         registry.addEndpoint("/webServer").withSockJS();  
  21.     }  
  22.   
  23. }  

 

 

这个类表示启用websocket消息处理,以及收发消息的域

config.enableSimpleBroker("/topic","/user");这句表示在topic和user这两个域上可以向客户端发消息;config.setUserDestinationPrefix("/user/");这句表示给指定用户发送(一对一)的主题前缀是“/user/”;  config.setApplicationDestinationPrefixes("/app"); 这句表示客户端向服务端发送时的主题上面需要加"/app"作为前缀;registry.addEndpoint("/webServer").withSockJS();这个和客户端创建连接时的url有关,后面在客户端的代码中可以看到。


下面是一个spring风格的controller,用于接收客户端的消息及响应客户端:

 

 

  1. import org.springframework.beans.factory.annotation.Autowired;  
  2. import org.springframework.messaging.handler.annotation.MessageMapping;  
  3. import org.springframework.messaging.handler.annotation.SendTo;  
  4. import org.springframework.messaging.simp.SimpMessagingTemplate;  
  5. import org.springframework.messaging.simp.annotation.SendToUser;  
  6. import org.springframework.stereotype.Controller;  
  7.   
  8. @Controller  
  9. public class WebSocketController {  
  10.   
  11.     public SimpMessagingTemplate template;  
  12.   
  13.     @Autowired  
  14.     public WebSocketController(SimpMessagingTemplate template) {  
  15.         this.template = template;  
  16.     }  
  17.   
  18.     @MessageMapping("/hello")  
  19.     @SendTo("/topic/hello")  
  20.     public Greeting greeting(Greeting message) throws Exception {  
  21.         return message;  
  22.     }  
  23.   
  24.     @MessageMapping("/message")  
  25.     @SendToUser("/message")  
  26.     public UserMessage userMessage(UserMessage userMessage) throws Exception {  
  27.         return userMessage;  
  28.     }  
  29.   
  30. }  

这个类里面织入SimpMessagingTemplate对象,后面动态发送消息时,需要用到这个对象。

 

第一个方法,表示服务端可以接收客户端通过主题“/app/hello”发送过来的消息,客户端需要在主题"/topic/hello"上监听并接收服务端发回的消息

第二个方法道理相同,只是注意这里用的是@SendToUser,这就是发送给单一客户端的标志。本例中,客户端接收一对一消息的主题应该是“/user/” + 用户Id + “/message” ,这里的用户id可以是一个普通的字符串,只要每个用户端都使用自己的id并且服务端知道每个用户的id就行。

这里的Greeting和UserMessage是一个普通的实现了序列化的Java bean

就这样,那么,在程序中的其他地方要动态发送消息,就是下面这两句代码:

 

  1. webSocketController.template.convertAndSend("/topic/hello",greeting) //广播  
  2. webSocketController.template.convertAndSendToUser(userId, "/message",userMessage) //一对一发送,发送特定的客户端  

 

 

 

 

客户端:

js客户端需要导入两个js组件:sockjs-0.3.4.js,stomp.js

 

  1. var url = 'http://localhost:8080/appRoot/webServer'  
  2. var socket = new SockJS(url, undefined, {protocols_whitelist: ['websocket']});  
  3. var stompClient = Stomp.over(socket);  
  4. stompClient.connect({}, function(frame) {  
  5.     stompClient.subscribe('/topic/hello', function(message){  
  6.         var json = JSON.parse(message.body);  
  7.     });  
  8.   
  9.      stompClient.subscribe('/user/' + userId + '/message', function(message){  
  10.          var messageEntity = JSON.parse(message.body);  
  11.     });  
  12. });  

 

第一个subscribe,是接收广播消息,第二个是接收一对一消息,其主题是'/user/' + userId+ '/message' , 不同客户端具有不同的userId

看到这里,你会发现,这里所谓的一对一,只是业务层面的一对一,也就是,需要不同客户端具有不同的userId才能实现,如果两个客户端使用相同的userid, 那么服务端给这个userId发送消息时,这两个客户端都会收到。要真正实现websocket技术层面的一对一发送,那就要使用websocket的session了。关于session方式,我这里上传一个demo,有兴趣可以下载:http://download.csdn.net/detail/valenon/8725195

© 著作权归作者所有

共有 人打赏支持
王福林
粉丝 10
博文 94
码字总数 37444
作品 0
徐汇
程序员
私信 提问
spring boot websocket stomp 实现广播通信和一对一通信聊天

一、前言 玩.net的时候,在asp.net下有一个叫 SignalR 的框架,可以在ASP .NET的Web项目中实现实时通信。刚接触java寻找先关替代品,发现 java 体系中有一套基于stomp协议的websocket通信的框...

ejiyuan
2018/07/11
0
0
Spring 4.0 中的 WebSocket 架构

两年前,客户端与服务器端的全双工双向通信作为一个很重要的功能被纳入到WebSocket RFC 6455协议中。在HTML5中,WebSocket已经成为一个流行词,大家对这个功能赋予很多构想,很多时候甚至是不...

oschina
2013/11/08
21.3K
26
SpringBoot-WebSocket-STMOP简介与使用

简介 WebSocket:是一种网络通信协议,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息详情 sockjs-client:js库,如果浏览器不支持 WebSocket,该库可以模拟对 WebSocke...

meijm0103
2018/09/06
0
0
spring 整合websoket(整理)

定义: + sockjs.js: 浏览器JavaScript库,它提供了一个类似于网络的对象。SockJS提供了一个连贯的、跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟、全双工、跨域通...

lxzh504
2018/08/08
0
0
在vue中使用SockJS实现webSocket通信

最近接到一个业务需求,需要做一个聊天信息的实时展示的界面,这就需要和服务器端建立webSocket连接,从而实现数据的实时获取和视图的实时刷新.在此将我的实现记录下来,希望可以给有同样需求的人...

慢思考快行动
2018/08/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

安装MyEclipse、激活MyEclipse、安装SVN插件

安装MyEclipse 1. 点击下载好的MyEclipse安装程序,弹出如下对话框,点击next 2. 勾选前面的方框,表示同意MyEclipse的协议,然后点击next。 3. 设置安装MyEclipse的路径,最好安装一个盘的根...

三度小姐
4分钟前
0
0
阿里巴巴的微服务开源之路

2019阿里云峰会·北京开发者专场 侠之大者,为国为民。 在金庸小说中,郭靖和黄蓉是“侠之大者,为国为民”的典范,他们以布衣之身帮助宋军守护襄阳十余年。 技术的世界里,并无大小之分。 ...

Mr_zebra
7分钟前
0
0
haproxy

Haproxy是一款免费、稳定、高效的轻量级负载均衡软件,现将其配置文件参数作如下说明: global #全局配置参数 global #全局配置参数 log 127.0.0.1 local3 info #日志级别 ...

拜了个拜
8分钟前
0
0
springmvc源码解析之@EnableWebMvc六

说在前面 本次主要介绍springmvc配置解析。更多精彩请关注“天河聊架构”微信公众号。 springmvc配置解析 @EnableWebMvc这个注解干了什么,初始化ViewResolver 进入到这个方法org.springfra...

天河2018
13分钟前
0
0
回调函数的那些事儿

实际工作中,对于回调函数一直是我不愿意去触碰的东西,一来由于被很多人搞得神秘兮兮的以为是很高深难懂的技术,二来在一般情况下通过互相包含类指针也能够解决问题,所以一直就不想去研究这...

rainbowcode
14分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部