spring websocket + stomp 实现广播通信和一对一通信<转>
spring对于基于stomp协议的websocket通信,其官网上面有一个guide,但是根据guide你只能写出来广播方式的通信,不能实现一对一的通信,这篇文章在这里把广播和一对一一起整理一下给大家。
服务端:
一,依赖,spring-websocket和spring-messaging,这里给出maven方式:
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-websocket</artifactId>
- <version>${spring-core.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-messaging</artifactId>
- <version>${spring-core.version}</version>
- </dependency>
二,服务端代码:
服务端的初始化,只需要两个类:WebsocketConfig和WebSocketController
- import org.springframework.context.annotation.Configuration;
- import org.springframework.messaging.simp.config.MessageBrokerRegistry;
- import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
- import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
- import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
- @Configuration
- @EnableWebSocketMessageBroker
- public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
- @Override
- public void configureMessageBroker(MessageBrokerRegistry config) {
- config.enableSimpleBroker("/topic","/user");
- config.setApplicationDestinationPrefixes("/app");
- config.setUserDestinationPrefix("/user/");
- }
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry.addEndpoint("/webServer").withSockJS();
- }
- }
这个类表示启用websocket消息处理,以及收发消息的域
config.enableSimpleBroker("/topic","/user");这句表示在topic和user这两个域上可以向客户端发消息;config.setUserDestinationPrefix("/user/");这句表示给指定用户发送(一对一)的主题前缀是“/user/”; config.setApplicationDestinationPrefixes("/app"); 这句表示客户端向服务端发送时的主题上面需要加"/app"作为前缀;registry.addEndpoint("/webServer").withSockJS();这个和客户端创建连接时的url有关,后面在客户端的代码中可以看到。
下面是一个spring风格的controller,用于接收客户端的消息及响应客户端:
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.messaging.handler.annotation.MessageMapping;
- import org.springframework.messaging.handler.annotation.SendTo;
- import org.springframework.messaging.simp.SimpMessagingTemplate;
- import org.springframework.messaging.simp.annotation.SendToUser;
- import org.springframework.stereotype.Controller;
- @Controller
- public class WebSocketController {
- public SimpMessagingTemplate template;
- @Autowired
- public WebSocketController(SimpMessagingTemplate template) {
- this.template = template;
- }
- @MessageMapping("/hello")
- @SendTo("/topic/hello")
- public Greeting greeting(Greeting message) throws Exception {
- return message;
- }
- @MessageMapping("/message")
- @SendToUser("/message")
- public UserMessage userMessage(UserMessage userMessage) throws Exception {
- return userMessage;
- }
- }
这个类里面织入SimpMessagingTemplate对象,后面动态发送消息时,需要用到这个对象。
第一个方法,表示服务端可以接收客户端通过主题“/app/hello”发送过来的消息,客户端需要在主题"/topic/hello"上监听并接收服务端发回的消息
第二个方法道理相同,只是注意这里用的是@SendToUser,这就是发送给单一客户端的标志。本例中,客户端接收一对一消息的主题应该是“/user/” + 用户Id + “/message” ,这里的用户id可以是一个普通的字符串,只要每个用户端都使用自己的id并且服务端知道每个用户的id就行。
这里的Greeting和UserMessage是一个普通的实现了序列化的Java bean
就这样,那么,在程序中的其他地方要动态发送消息,就是下面这两句代码:
- webSocketController.template.convertAndSend("/topic/hello",greeting) //广播
- webSocketController.template.convertAndSendToUser(userId, "/message",userMessage) //一对一发送,发送特定的客户端
客户端:
js客户端需要导入两个js组件:sockjs-0.3.4.js,stomp.js
- var url = 'http://localhost:8080/appRoot/webServer'
- var socket = new SockJS(url, undefined, {protocols_whitelist: ['websocket']});
- var stompClient = Stomp.over(socket);
- stompClient.connect({}, function(frame) {
- stompClient.subscribe('/topic/hello', function(message){
- var json = JSON.parse(message.body);
- });
- stompClient.subscribe('/user/' + userId + '/message', function(message){
- var messageEntity = JSON.parse(message.body);
- });
- });
第一个subscribe,是接收广播消息,第二个是接收一对一消息,其主题是'/user/' + userId+ '/message' , 不同客户端具有不同的userId
看到这里,你会发现,这里所谓的一对一,只是业务层面的一对一,也就是,需要不同客户端具有不同的userId才能实现,如果两个客户端使用相同的userid, 那么服务端给这个userId发送消息时,这两个客户端都会收到。要真正实现websocket技术层面的一对一发送,那就要使用websocket的session了。关于session方式,我这里上传一个demo,有兴趣可以下载:http://download.csdn.net/detail/valenon/8725195
spring websocket + stomp 实现广播通信和一对一通信<转>的更多相关文章
- spring boot websocket stomp 实现广播通信和一对一通信聊天
一.前言 玩.net的时候,在asp.net下有一个叫 SignalR 的框架,可以在ASP .NET的Web项目中实现实时通信.刚接触java寻找相关替代品,发现 java 体系中有一套基于stom ...
- Spring 学习——基于Spring WebSocket 和STOMP实现简单的聊天功能
本篇主要讲解如何使用Spring websocket 和STOMP搭建一个简单的聊天功能项目,里面使用到的技术,如websocket和STOMP等会简单介绍,不会太深,如果对相关介绍不是很了解的,请自 ...
- spring websocket 和socketjs实现单聊群聊,广播的消息推送详解
spring websocket 和socketjs实现单聊群聊,广播的消息推送详解 WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随 ...
- spring+rabbitmq+stomp搭建websocket消息推送(非spring boot方式)
前言: 两年前做过spring+activemq+stomp的ws推送,那个做起来很简单,但现在公司用的mq中间件是rabbitmq,因此需要通过rabbitmq去做ws通信.仔细搜了搜百度/谷歌,网 ...
- Spring Boot 中使用 WebSocket 实现一对多聊天及一对一聊天
为什么需要WebSocket? 我们已经有了http协议,为什么还需要另外一个协议?有什么好处? 比如我想得到价格变化,只能是客户端想服务端发起请求,服务器返回结果,HTTP协议做不到服务器主动向客户 ...
- java WebSocket的实现以及Spring WebSocket
开始学习WebSocket,准备用它来实现一个在页面实时输出log4j的日志以及控制台的日志. 首先知道一些基础信息: java7 开始支持WebSocket,并且只是做了定义,并未实现 tomcat ...
- spring WebSocket详解
场景 websocket是Html5新增加特性之一,目的是浏览器与服务端建立全双工的通信方式,解决http请求-响应带来过多的资源消耗,同时对特殊场景应用提供了全新的实现方式,比如聊天.股票交易.游戏 ...
- Spring WebSocket教程(一)
学习背景 很久以前就知道WebSocket,但那时不论是浏览器还是开发技术对它的支持都还很少.但是,Spring4突然发布,让我眼前一亮,Spring4直接支持WebSocket. 对于Spring我 ...
- spring websocket集群问题的简单记录
目录 前言 解决方案 代码示例 前言 最近公司里遇到一个问题,在集群中一些websocket的消息丢失了. 产生问题的原理很简单,发送消息的服务和接收者连接的服务不是同一个服务. 解决方案 用中间件( ...
随机推荐
- OPENSSL编程起步
原文链接: http://blog.csdn.net/itmes/article/details/7711076 WINDOWS平台下OPENSSL的编译和安装使用 OPENSSL是开放源代码的,可以 ...
- MySQL参数优化案例
环境介绍 优化层级与指导思想 优化过程 最小化安装情况下的性能表现 优化innodb_buffer_pool_size 优化innodb_log_files_in_group&innodb_l ...
- unity, ios skin crash
https://issuetracker.unity3d.com/issues/ios-loading-models-with-tangents-set-to-calculate-legacy-fro ...
- zookeeper 启动脚本
#!/bin/bash export JAVA_HOME=/usr/java/latest export JRE_HOME=/usr/java/latest/jre zoo=/data/package ...
- 关于ansbile工具的shell、command、script、raw模块的区别和使用场景
command模块 [执行远程命令] [root@node1 ansible]# ansible testservers -m command -a 'uname -n' script模块 [在远程主 ...
- Using ADB and fastboot
What is adb? The Android Debug Bridge (adb) is a development tool that facilitates communication bet ...
- android源码编译-Mac 10.11 xcode5.1.1
第一步: 参考官网:创建一个dmg,大小80g,这个要尽量大一点,40g感觉不够用:http://source.android.com/source/initializing.html 第二步:下载a ...
- 外部程序启动App
第一种:直接通过包名: Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.joyodream. ...
- Pycrypto与RSA密码技术笔记
密码与通信 密码技术是一门历史悠久的技术.信息传播离不开加密与解密.密码技术的用途主要源于两个方面,加密/解密和签名/验签 在信息传播中,通常有发送者,接受者和窃听者三个角色.假设发送者Master想 ...
- dom4j: 生成的XML文件根节点 xmlns="" 的问题
使用dom4j写入XML文件时,写入完毕后发现root element中没有 xmlns,也即是没有命名空间. 正确的写法如下: Document document = DocumentHelper. ...