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的消息丢失了. 产生问题的原理很简单,发送消息的服务和接收者连接的服务不是同一个服务. 解决方案 用中间件( ...
随机推荐
- cassandra运行出现了Unable to gossip with any seeds,cqlsh链接不上,提示connection refused处理办法
cassandra运行出现了Unable to gossip with any seeds,cqlsh链接不上,提示connection refused处理办法 问题描述 当启动了cassandra之 ...
- linux中WDCP的日志彻底删除技巧
apache或nginx都有开关默认日志,一个是正常访问日志,一个是错误的日志,目录在 /www/wdlinux/nginx-1.0.15/logs /www/wdlinux/httpd-2.2.22 ...
- [转]Java中使用Runtime和Process类运行外部程序
帖子1: 使用Runtime.getRuntime().exec()方法可以在java程序里运行外部程序. 1. exec(String command) 2. exec(String comma ...
- php实现ZIP压缩文件解压缩(转)
测试使用了两个办法都可以实现: 第一个:需要开启配置php_aip.dll <?php //需开启配置 php_zip.dll //phpinfo(); header("Content ...
- django -- 为model 指定数据库名
一.为model指定数据库名: django自己实现的ORM中.如果要指定一个model的表名是通过Meta类来实现的. from django.db import models # Create y ...
- ${HADOOP_CONF_DIR:-$HADOOP_PREFIX/$DEFAULT_CONF_DIR}
在hadoop-config.sh中,有如下语句:${HADOOP_CONF_DIR:-$HADOOP_PREFIX/$DEFAULT_CONF_DIR} ...
- /etc/ssh/sshd_config 关建字:PermitRootLogin no 禁示以root身份登录服务器
这种情况,不会影响,普通用户su到root
- 【小白的CFD之旅】24 稳态和瞬态
小白最近在练习案例的时候,对稳态和瞬态的问题,产生了一些疑问.譬如说,为什么有的案例用稳态,而有的案例用瞬态?有时候相同的案例既可以用稳态也可以用瞬态,而有的案例却只能用瞬态计算?小白决定找小牛师兄问 ...
- 每日英语:China to Move Slowly on One-Child Law Reform
BEIJING—China's family-planning agency is projecting a slow rollout for an easing of its one-child p ...
- 【Windows】windows核心编程整理(上)
小续 这是我11年看<windows核心编程>时所作的一些笔记,现整理出来共享给大家 windows核心编程整理(上) windows核心编程整理(下) 线程的基础知识 进程是不活泼的,进 ...