使用spring websocket 和stomp实现消息功能
2016-07-23 18:49
751 查看
实现一个消息驱动pojo
public class MarcHandler extends AbstractWebSocketHandler{ private Logger LOGGER = LoggerFactory.getLogger(MarcHandler.class); @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { LOGGER.info("received Message :"+ message.getPayload()); Thread.sleep(2000); session.sendMessage(new TextMessage("Polo!")); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { LOGGER.info("session closed!"); } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { LOGGER.info("session established!"); } }
配置websocket handler 和js demo
原生websocket配置
<websocket:handlers > <websocket:mapping path="/marco" handler="marcHandler"/> <!--<websocket:sockjs/>--> </websocket:handlers>js demo:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <html> <head> <title>Home</title> <spring:url value="/webjars/jquery/2.0.3/jquery.min.js" var="jQueryCore"/> <script src="${jQueryCore}"></script> <spring:url value="/webjars/sockjs-client/0.3.4/sockjs.min.js" var="sockJs"/> <script src="${sockJs}"></script> </head> <body> <button id="stop">Stop</button> <script style="text/javascript"> $(function () { var wsUrl = "ws://"+window.location.host+"/japi-rest/marco" var sock = new WebSocket(wsUrl); // var SockJSUrl = "http://"+window.location.host+"/japi-rest/marco" // var sock = new SockJS(SockJSUrl); sock.onopen = function() { console.log('Opening'); sayMarco(); } sock.onmessage = function(e) { console.log('Received message: ', e.data); $('#output').append('Received "' + e.data + '"<br/>'); setTimeout(function(){sayMarco()}, 2000); } sock.onclose = function() { console.log('Closing'); } function sayMarco() { console.log('Sending Marco!'); $('#output').append('Sending "Marco!"<br/>'); sock.send("Marco!"); } $('#stop').click(function() {sock.close()}); }) </script> <div id="output"></div> </body> </html>PS: 1)如果打开 <websocket:sockjs/> 会报错:WebSocket connection to 'ws://localhost:8080/japi-rest/marco' failed: Error during WebSocket handshake: Unexpected response code: 200
利用SockJs解决部分浏览器不支持websocket
<websocket:handlers> <websocket:mapping path="/marco" handler="marcHandler"/> <websocket:sockjs/> </websocket:handlers>
JS Demo:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %><html><head><title>Home</title><spring:url value="/webjars/jquery/2.0.3/jquery.min.js" var="jQueryCore"/><script src="${jQueryCore}"></script><spring:url value="/webjars/sockjs-client/0.3.4/sockjs.min.js" var="sockJs"/><script src="${sockJs}"></script></head><body><button id="stop">Stop</button><script style="text/javascript">$(function () {// var wsUrl = "ws://"+window.location.host+"/japi-rest/marco"// var sock = new WebSocket(wsUrl);var SockJSUrl = "http://"+window.location.host+"/japi-rest/marco"var sock = new SockJS(SockJSUrl);sock.onopen = function() {console.log('Opening');sayMarco();}sock.onmessage = function(e) {console.log('Received message: ', e.data);$('#output').append('Received "' + e.data + '"<br/>');setTimeout(function(){sayMarco()}, 2000);}sock.onclose = function() {console.log('Closing');}function sayMarco() {console.log('Sending Marco!');$('#output').append('Sending "Marco!"<br/>');sock.send("Marco!");}$('#stop').click(function() {sock.close()});})</script><div id="output"></div></body></html>
使用STOMP 消息
如果直接用websocket 编写web应用 类似与直接使用tcp套接字, stomp 相当于基于websocket之上的一个高层级的线路协议), xml配置:<!-- stomp and message broker config start --><websocket:message-broker application-destination-prefix="/app"><!-- websocket 底层连接地址 --><websocket:stomp-endpoint path="/marcopolo" ><websocket:sockjs/></websocket:stomp-endpoint><websocket:simple-broker prefix="/topic,/queue" /></websocket:message-broker><!-- stomp and message broker config end-->编写一个消息处理controller:
@Controllerpublic class MarcoController {private final static Logger logger = LoggerFactory.getLogger(MarcoController.class);@MessageMapping("/marco")public Shout handleShout(Shout incoming) {logger.info("Received message: " + incoming.getMessage());try { Thread.sleep(2000); } catch (InterruptedException e) {}Shout outgoing = new Shout();outgoing.setMessage("Polo!");return outgoing;}}js 编写测试客户端:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %><html><head><title>Home</title><spring:url value="/webjars/jquery/2.0.3/jquery.min.js" var="jQueryCore"/><script src="${jQueryCore}"></script><spring:url value="/webjars/sockjs-client/0.3.4/sockjs.min.js" var="sockJs"/><script src="${sockJs}"></script><spring:url value="/webjars/stomp-websocket/2.3.4/lib/stomp.min.js" var="stomp"/><script src="${stomp}"></script><spring:url value="/" var="context"/></head><body><button id="stop">Stop</button><script th:inline="javascript">var sock = new SockJS("${context}"+"/marcopolo");var stomp = Stomp.over(sock);stomp.connect('guest', 'guest', function(frame) {console.log('***** Connected *****');stomp.subscribe("/topic/marco", handlePolo);sayMarco();});function handleOneTime(message) {console.log('Received: ', message);}function handlePolo(message) {console.log('Received: ', message);$('#output').append("<b>Received: " +JSON.parse(message.body).message + "</b><br/>")if (JSON.parse(message.body).message === 'Polo!') {setTimeout(function(){sayMarco()}, 2000);}}function handleErrors(message) {console.log('RECEIVED ERROR: ', message);$('#output').append("<b>GOT AN ERROR!!!: " +JSON.parse(message.body).message + "</b><br/>")}function sayMarco() {console.log('Sending Marco!');stomp.send("/app/marco", {},JSON.stringify({ 'message': 'Marco!' }));// stomp.send("/topic/marco", {},// JSON.stringify({ 'message': 'Marco!' }));$('#output').append("<b>Send: Marco!</b><br/>")}$('#stop').click(function() {sock.close()});</script><div id="output"></div></body></html>PS:0) stomap 消息道理数据流程图:1)<websocket:stomp-endpoint path="/marcopolo" > 这个配置终端 表明底层的websocket url2)application-destination-prefix="/app" 是 controller处理的path 前缀3) <websocket:simple-broker prefix="/topic,/queue" /> 配置了两个代理的目的地4) @MessageMapping("/marco") 这个注解的方法返回的数据写到哪个代理目的地呢?因为没有配置@SendTo 所以默认写到/topic +"/marco" ,见下图调试:
相关文章推荐
- 2015-2016网页设计趋势分析 Web Design of Trends
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring AOP动态代理-切面
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- 监听器获取Spring配置文件的方法
- Java利用Sping框架编写RPC远程过程调用服务的教程
- springmvc 发送ajax出现中文乱码的解决方法汇总
- Spring MVC中Ajax实现二级联动的简单实例
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的