找了很多配置文档及实例说明,也还是没能成功,最终在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实现服务端主动向客户端发送消息相关推荐

  1. android java websocket client_websocket服务端,android客户端示例

    服务端库依赖详见章末 #####spring websocket服务端代码(会话过程) public class HandshakeInterceptor extends HttpSessionHan ...

  2. Tomcat中实现websocket和browser端访问

    Tomcat中实现websocket和browser端访问 简介: 在tomcat 7.0.27版本后,实现了对websocket的支持.在最新的tomcat7.0.72后,websocket的开发变 ...

  3. js ws 状态_node.js中ws模块创建服务端和客户端,网页WebSocket客户端

    首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...

  4. node.js中ws模块创建服务端和客户端,网页WebSocket客户端

    首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...

  5. springboot+websocket实现服务端、客户端

    一.引言 小编最近一直在使用springboot框架开发项目,毕竟现在很多公司都在采用此框架,之后小编也会陆续写关于springboot开发常用功能的文章. 什么场景下会要使用到websocket的呢 ...

  6. SpringBoot(23) 集成socket.io服务端和客户端实现通信

    一.前言 websocket和socket.io区别? websocket 一种让客户端和服务器之间能进行双向实时通信的技术 使用时,虽然主流浏览器都已经支持,但仍然可能有不兼容的情况 适合用于cli ...

  7. 使用HTML5的WebSocket实现服务端和客户端数据通信(有演示和源码)

    WebSocket协议是基于TCP的一种新的网络协议.WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术.依靠这种技术可以实现客户端和服务器端的长连接,双向实时通信. ...

  8. flux服务器推消息,服务端主动推送数据,除了 WebSocket 你还能想到啥?

    原标题:服务端主动推送数据,除了 WebSocket 你还能想到啥? 来自公众号: 江南一点雨 在 上篇文章 中,松哥和大家分享了 WebFlux 的基本用法,小伙伴们已经了解到使用 WebFlux ...

  9. appollo消息服务器,Springboot 集成 MQTT —— web 服务端实现(apollo 客户端)-Go语言中文社区...

    基于 MQTT 可以实现很多场景,例如现在使用比较多的物联网,还有消息的实时推送.联网的设备连接上 apollo 服务器以后,一直监听 apollo 推送过来的信令/消息即可. 1.web 服务端向联 ...

最新文章

  1. 状态机系列学习笔记01
  2. 谷歌量子计算突破引爆学界,作者亲自回应质疑,国内专家点评
  3. python如何导入matlab数据,python学习-python到matlab数据的传输
  4. Java 8 中处理日期和时间示例
  5. windows live writer test…
  6. future 线程报错后_线程池运用实例——一次错误的多线程程序设计以及修复过程...
  7. react的导出是怎么实现的_从零开始开发一个 React
  8. HttpClient FormUrlEncodedContent System.UriFormatException: 无效的 URI: URI 字符串太长问题解决方案
  9. .NET开发中的Exception处理三定律[转]
  10. linux中crontab的用法
  11. C# 实现自定义的USB设备与上位机进行通信(上位机部分)
  12. tensorflow.python.framework.errors_impl.UnimplementedError: Cast string to int64 is not supported
  13. 强制刷机NOKIA E6-00方法
  14. 普通IO口模拟实现SPI通信及应用解析
  15. 在html里怎么在图片在添加文字,在HTML中,怎么在图片上添加文字?
  16. 形而上学 “形而上者谓之道,形而下者谓之器”
  17. GeckoView:Mozilla面向移动浏览器打造的渲染引擎
  18. R语言可视化回归模型的残差直方图并进行残差分析(Histogram of Residuals)
  19. 11款学习编程好玩的浏览器游戏
  20. C语言实现简单的线程池【转】

热门文章

  1. R语言对dataframe的行数据进行排序(Ordering rows)实战:使用R原生方法、data.table、dplyr等方案
  2. R语言使用Rtsne包进行TSNE分析:通过数据类型筛选数值数据、scale函数进行数据标准化缩放、提取TSNE分析结果合并到原dataframe中(tSNE with Rtsne package)
  3. R语言ggplot2可视化:ggplot2可视化半小提琴图(Half Violin Plots)
  4. Python将彩色图转换为灰度图
  5. Kinesis、Streams and Firehose
  6. c4android资源,OpenC4Android开发环境搭.doc
  7. (邓爱萍)类 对象 例题
  8. axt测试软件,【测试工具】这些APP实用测试工具,不知道你就out了!
  9. java 庖丁解牛api_Java Restful API Best Practices
  10. 九、调度算法的评价指标