ssm配置socket_ssm框架中集成websocket实现服务端主动向客户端发送消息
找了很多配置文档及实例说明,也还是没能成功,最终在csdn博客中发现了基于stomp的消息推送的文章,
下面整理自csdn博客,https://blog.csdn.net/u013627689/article/details/73611945
1. 加入spring的webSocket包,必须是4.0以上的包
加入jar的依赖:
spring-messaging-{spring.version}.jar
spring-websocket-{spring.version}.jar
2. 通信要异步处理,所以在 web.xml 里的filter 和servlet 都要加上异步的支持,默认是同步的。
true
3. 在spring-mvc配置文件中,声明bean
class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
4. net.jileniao.ssm.websocket.WebSocketMessageUtil的代码
package net.jileniao.ssm.websocket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.util.StringUtils;
/**
* 这里启动一个线程不停的监控队列是否有消息需要进行发送,如果有就发送出去。
*
*/
public class WebSocketMessageUtil implements Runnable {
static Logger log = Logger.getLogger(WebSocketMessageUtil.class);
private static SimpMessagingTemplate messageingTemplate;
private static BlockingQueue wsQueue = new LinkedBlockingDeque<>();
public WebSocketMessageUtil() {
new Thread(this).start();
}
@Autowired
public void setTemplate(SimpMessagingTemplate t) {
WebSocketMessageUtil.messageingTemplate = t;
}
public static void addMessage(WebSocketMessage msg) {
try {
wsQueue.put(msg);
} catch (InterruptedException e) {
log.error("添加实时消息异常");
}
}
public static void sendMessage(WebSocketMessage msg) {
if (StringUtils.isEmpty(msg.getUserId())) {
messageingTemplate.convertAndSend(msg.getDistination(), msg);
} else {
messageingTemplate.convertAndSendToUser(msg.getUserId(), msg.getDistination(), msg);
}
}
@Override
public void run() {
log.info(">>>>>>>推送消息线程启动,正在监听消息。");
while (true) {
try {
WebSocketMessage msg = wsQueue.take();
if (msg != null) {
WebSocketMessageUtil.sendMessage(msg);
}
} catch (Exception ex) {
}
}
}
}
5.使用注解配置定义的webSocket的配置类
package net.jileniao.ssm.websocket;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@EnableWebSocketMessageBroker
@Controller
public class WebSocketMessageAction extends AbstractWebSocketMessageBrokerConfigurer {
/**
* 将"/webSocket"路径注册为STOMP端点,这个路径与发送和接收消息的目的路径有所不同,
* 这是一个端点,客户端在订阅或发布消息到目的地址前,要连接该端点,
* 即用户发送请求url="/applicationName/webSocket"与STOMP server进行连接。之后再转发到订阅url;
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 注册websocket,客户端用ws://host:port/项目名/webSocket 访问
registry.addEndpoint("/webSocket").setHandshakeHandler(new StompMessageHandshakeHandler())
.addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();// 表示支持以SockJS方式连接服务器
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 这句话表示在topic和user这两个域上服务端可以向客户端发消息
registry.enableSimpleBroker("/topic", "/user");
// 这句话表示客户端向服务器端发送时的主题上面需要加"/ws"作为前缀
registry.setApplicationDestinationPrefixes("/ws");
// 这句话表示服务端给客户端指定用户发送一对一的主题,前缀是"/user"
registry.setUserDestinationPrefix("/user");
}
}
6.其中StompMessageHandshakeHandler类代码如下
package net.jileniao.ssm.websocket;
import java.security.Principal;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
/**
* 获取客户端连接前对客户端的session、cookie等信息进行握手处理,
* 也就是可以在这里可以进行一些用户认证? 这是我个人的理解。这里没有做任何处理
*
*/
public class StompMessageHandshakeHandler extends DefaultHandshakeHandler {
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler,
Map attributes) {
return super.determineUser(request, wsHandler, attributes);
}
}
7.其中WebSocketHandshakeInterceptor的程序代码如下
package net.jileniao.ssm.websocket;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
/**
* 握手前后的拦截,这里没有处理,默认
*
*/
public class WebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
return super.beforeHandshake(request, response, wsHandler, attributes);
}
}
8.其中WebSocketHandshakeHandler的程序代码如下
package net.jileniao.ssm.websocket;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
/**
* WebSocket 握手信息
*
* @ClassName: WebSocketHandshakeHandler.java
* @Description: WebSocket 握手信息
*/
public class WebSocketHandshakeHandler extends TextWebSocketHandler {
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
super.afterConnectionClosed(session, status);
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage> message) throws Exception {
super.handleMessage(session, message);
}
}
9.剩下就是工具辅助类了,首先是WebSocketMessage,自己封装的消息体
package net.jileniao.ssm.websocket;
/**
* 自定义封装包含发送信息的实体类
*
*/
public class WebSocketMessage {
/**
* 发送广播消息,发送地址:/topic/* ,*为任意名字,如取名monitor,则客户端对应订阅地址为:/topic/monitor
* 发送私人消息,发送地址:/*,*为任意名字,这里取名为message,客户端对应订阅地址:/user/{自定义客户端标识ID}/message
*/
private String distination;
private Object data;// 实际发送的数据对象
private String userId;// 如果不为空,则表示发送给个人而不是广播
public String getDistination() {
return distination;
}
public void setDistination(String distination) {
this.distination = distination;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
10. 测试发送消息
有了上面的配置资源及代码之后,就可以测试在服务器上给客户端发送消息,发送消息使用下面的代码
WebSocketMessage message = new WebSocketMessage();
message.setDistination("/topic/jileniao/testWebSocket/new");
message.setData("A message from the server....");
WebSocketMessageUtil.addMessage(message);
11.客户端要接收,下面是客户端的页面程序。
WebSocket测试
Connect
Disconnect
What is your name?
Send all
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}
function connect() {
// 地址:工程名/webSocket
// 连接服务端的端点,连接以后才可以订阅广播消息和个人消息
var socket = new SockJS('/ssm/webSocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
// 订阅广播消息
stompClient.subscribe('/topic/jileniao/testWebSocket/new', function(playload) {
console.log(JSON.stringify(playload));
});
// 订阅个人信息
stompClient.subscribe('/user/1/testUser', function(playload) {
console.log(JSON.stringify(playload));
});
});
}
function disconnect() {
if(stompClient != null) {
stompClient.disconnect();
console.log("Disconnected");
}
}
//发送到服务的消息
function sendName() {
var name = document.getElementById('name').value;
stompClient.send("../ws/webSocket/testWithServer", {
'name': 'Jileniao',
'syn': 'Zhang'
}, JSON.stringify({
'message': name
}));
}
OK。再次感谢csdn原博主。
分享本文至:
WRITTEN BY
极乐鸟博客http://jileniao.net
ssm配置socket_ssm框架中集成websocket实现服务端主动向客户端发送消息相关推荐
- android java websocket client_websocket服务端,android客户端示例
服务端库依赖详见章末 #####spring websocket服务端代码(会话过程) public class HandshakeInterceptor extends HttpSessionHan ...
- Tomcat中实现websocket和browser端访问
Tomcat中实现websocket和browser端访问 简介: 在tomcat 7.0.27版本后,实现了对websocket的支持.在最新的tomcat7.0.72后,websocket的开发变 ...
- js ws 状态_node.js中ws模块创建服务端和客户端,网页WebSocket客户端
首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...
- node.js中ws模块创建服务端和客户端,网页WebSocket客户端
首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...
- springboot+websocket实现服务端、客户端
一.引言 小编最近一直在使用springboot框架开发项目,毕竟现在很多公司都在采用此框架,之后小编也会陆续写关于springboot开发常用功能的文章. 什么场景下会要使用到websocket的呢 ...
- SpringBoot(23) 集成socket.io服务端和客户端实现通信
一.前言 websocket和socket.io区别? websocket 一种让客户端和服务器之间能进行双向实时通信的技术 使用时,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况 适合用于cli ...
- 使用HTML5的WebSocket实现服务端和客户端数据通信(有演示和源码)
WebSocket协议是基于TCP的一种新的网络协议.WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术.依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信. ...
- flux服务器推消息,服务端主动推送数据,除了 WebSocket 你还能想到啥?
原标题:服务端主动推送数据,除了 WebSocket 你还能想到啥? 来自公众号: 江南一点雨 在 上篇文章 中,松哥和大家分享了 WebFlux 的基本用法,小伙伴们已经了解到使用 WebFlux ...
- appollo消息服务器,Springboot 集成 MQTT —— web 服务端实现(apollo 客户端)-Go语言中文社区...
基于 MQTT 可以实现很多场景,例如现在使用比较多的物联网,还有消息的实时推送.联网的设备连接上 apollo 服务器以后,一直监听 apollo 推送过来的信令/消息即可. 1.web 服务端向联 ...
最新文章
- 状态机系列学习笔记01
- 谷歌量子计算突破引爆学界,作者亲自回应质疑,国内专家点评
- python如何导入matlab数据,python学习-python到matlab数据的传输
- Java 8 中处理日期和时间示例
- windows live writer test…
- future 线程报错后_线程池运用实例——一次错误的多线程程序设计以及修复过程...
- react的导出是怎么实现的_从零开始开发一个 React
- HttpClient FormUrlEncodedContent System.UriFormatException: 无效的 URI: URI 字符串太长问题解决方案
- .NET开发中的Exception处理三定律[转]
- linux中crontab的用法
- C# 实现自定义的USB设备与上位机进行通信(上位机部分)
- tensorflow.python.framework.errors_impl.UnimplementedError: Cast string to int64 is not supported
- 强制刷机NOKIA E6-00方法
- 普通IO口模拟实现SPI通信及应用解析
- 在html里怎么在图片在添加文字,在HTML中,怎么在图片上添加文字?
- 形而上学 “形而上者谓之道,形而下者谓之器”
- GeckoView:Mozilla面向移动浏览器打造的渲染引擎
- R语言可视化回归模型的残差直方图并进行残差分析(Histogram of Residuals)
- 11款学习编程好玩的浏览器游戏
- C语言实现简单的线程池【转】
热门文章
- R语言对dataframe的行数据进行排序(Ordering rows)实战:使用R原生方法、data.table、dplyr等方案
- R语言使用Rtsne包进行TSNE分析:通过数据类型筛选数值数据、scale函数进行数据标准化缩放、提取TSNE分析结果合并到原dataframe中(tSNE with Rtsne package)
- R语言ggplot2可视化:ggplot2可视化半小提琴图(Half Violin Plots)
- Python将彩色图转换为灰度图
- Kinesis、Streams and Firehose
- c4android资源,OpenC4Android开发环境搭.doc
- (邓爱萍)类 对象 例题
- axt测试软件,【测试工具】这些APP实用测试工具,不知道你就out了!
- java 庖丁解牛api_Java Restful API Best Practices
- 九、调度算法的评价指标