spring websocket 使用@SendToUser
来源:互联网 发布:欧陆风云4 mac 下载 编辑:程序博客网 时间:2024/05/29 10:19
之前我们利用@SendTo在方法上进行注解,方法的返回值会被messageconverter转化并推送到消息代理器中,由消息代理器广播到订阅路径去
@MessageMapping("bar") //@MessageMapping接收客户端消息@SendTo("/topic/brocast") //@SendTo广播消息出去public String handle1(String msg) { return msg;}
上面msg会被广播到”/topic/brocast”这个订阅路径中,只要客户端订阅了这条路径,不管是哪个用户,都会接收到消息
那么需求来了,如果我只是想简单的用websocket向服务器请求资源而已,然后服务器你就把资源给我就行了,别的用户就不用你广播推送了,简单点,就是我请求,你就推送给我。
spring websocket 可以使用@SendToUser做到这一点,在使用@SendToUser之前,我们需要明白以下几点:
1.spring webscoket通道的建立最开始还是源于http协议的第一次握手,握手成功之后,就打开了浏览器和服务器的webscoket通过,这时,httprequest中的登录授权信息即javax.security.Principal会被绑定到websocket的session中
2.spring webscoket能识别带”/user”的订阅路径并做出处理,例如,如果浏览器客户端,订阅了’/user/topic/greetings’这条路径,
stompClient.subscribe('/user/topic/greetings', function(data) { //...});
就会被spring websocket利用UserDestinationMessageHandler进行转化成”/topic/greetings-usererbgz2rq”,”usererbgz2rq”中,user是关键字,erbgz2rq是sessionid,这样子就把用户和订阅路径唯一的匹配起来了
3.spring webscoket在使用@SendToUser广播消息的时候,
@MessageMapping("handle") @SendToUser("/topic/greetings")public String handle(String msg) { //... return msg;}
“/topic/greetings”会被UserDestinationMessageHandler转化成”/user/role1/topic/greetings”,role1是用户的登录帐号,这样子就把消息唯一的推送到请求者的订阅路径中去,这时候,如果一个帐号打开了多个浏览器窗口,也就是打开了多个websocket session通道,这时,spring webscoket默认会把消息推送到同一个帐号不同的session,你可以利用broadcast = false把避免推送到所有的session中
@MessageMapping("handle") @SendToUser(value = "/topic/greetings",broadcast = false)public String handle(String msg) { //... return name;}
下面来做个demo,首先是服务器要配置登录验证权限,这里利用tomcat的basic安全验证,在web.xml里面配置
<security-constraint><web-resource-collection> <web-resource-name>protect resources </web-resource-name> <url-pattern>/*</url-pattern> <http-method>HEAD</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> </web-resource-collection> <auth-constraint> <role-name>role1</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint></security-constraint><login-config> <auth-method>BASIC</auth-method></login-config><security-role> <description>Role1</description> <role-name>role1</role-name></security-role>
role1是登录的角色名,其中验证信息可以在tomcat-users.xml里面配置
<role rolename="tomcat"/> <role rolename="role1"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="role1" password="tomcat" roles="role1"/>
这里有俩个帐号,role1和both,角色都有role1,password都是tomcat,我们可以利用这俩个帐号在IE9和谷歌浏览器进行登录
然后服务器,我们分别使用@SendTo和@SendToUser进行广播推送和精准推送
首先我们注册下spring webscoket服务器
@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { //portfolio-stomp就是websocket的端点,客户端需要注册这个端点进行链接,withSockJS允许客户端利用sockjs进行浏览器兼容性处理 registry.addEndpoint("/portfolio-stomp").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); //设置服务器广播消息的基础路径 registry.setApplicationDestinationPrefixes("/app"); //设置客户端订阅消息的基础路径 registry.setPathMatcher(new AntPathMatcher(".")); //可以已“.”来分割路径,看看类级别的@messageMapping和方法级别的@messageMapping } @Override public boolean configureMessageConverters(List<MessageConverter> messageConverters) { return true; } @Override public void configureWebSocketTransport(WebSocketTransportRegistration registry) { // TODO Auto-generated method stub registry.addDecoratorFactory(new MyWebSocketHandlerDecoratorFactory()); } @Override public void configureClientInboundChannel(ChannelRegistration registration) { registration.setInterceptors(new MyChannelInterceptor()); } @Override public void configureClientOutboundChannel(ChannelRegistration registration) { // TODO Auto-generated method stub } @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { // TODO Auto-generated method stub } @Override public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { // TODO Auto-generated method stub }}
然后写下服务的的接收和发送
@Controller@RequestMapping("/webSocket")@MessageMapping("foo")public class WebSocketController { /** * 精准推送 * @param msg * @param principal * @return */ @MessageMapping("handle1") @SendToUser(value = "/topic/greetings1",broadcast = false) public String handle1(String msg,Principal principal) { return "精准推送,只推送到" + principal.getName(); } /** * 广播推送 * @param msg * @param principal * @return */ @MessageMapping("handle2") @SendTo("topic/greetings2") public String handle2(String msg,Principal principal) { return "广播推送,所有用户都收得到"; } }
最后在浏览器客户端,我们利用sockjs和stomp.js链接并发送和订阅消息,其中在websocket.js代码就是这样子的
var socket = new SockJS('/whats/portfolio-stomp');var stompClient = Stomp.over(socket);stompClient.connect({}, function(frame) {stompClient.subscribe('/user/topic/greetings1', function(data) { $("#ret").text(data.body); }); stompClient.subscribe('/topic/greetings2', function(data) { $("#ret").text(data.body); });});/** * 精准推送 */document.getElementById("ws1").onclick = function() { stompClient.send("/app/foo.handle2",{},{ msg : "精准推送" });}/** * 广播推送 */document.getElementById("ws").onclick = function() { stompClient.send("/app/foo.handle1",{},{ msg : "广播推送" });}
jsp页面其实就是这样子的
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html ><html><head><meta charset="UTF-8"><title>websocket</title></head><body> <h1>hello websocket client !!</h1><button id = "ws">精准推送</button><button id = "ws1">广播推送</button><span id ="ret"></span><script type="text/javascript" src="${pageContext.request.contextPath}/content/uilib/websocket/sockjs-1.0.3.js"></script><script type="text/javascript" src="${pageContext.request.contextPath}/content/uilib/websocket/stomp.js"></script><script type="text/javascript" src="${pageContext.request.contextPath}/content/js/websocket/websocket.js"></script></body></html>
到这里就完成了功能了
精准推送
广播推送
- spring websocket 使用@SendToUser
- spring websocket 使用@SendToUser
- Spring websocket 使用
- spring+websocket整合使用
- 【spring+websocket的使用】
- Spring Websocket 使用笔记
- 使用spring-websocket包搭建websocket服务
- Spring-messaging (STOMP) @SendTo 与 @SendToUser的区别
- Spring-WebSocket配置以及使用
- Spring Boot 使用 WebSocket 实现消息推送 及 WebSocket原理
- 使用XML配置spring-websocket服务
- Spring WebSocket使用token认证连接
- 使用Spring WebSocket实现消息推送
- Spring WebSocket
- spring websocket
- spring websocket
- WebSocket Spring
- Spring WebSocket
- ubuntu emacs setup
- poj 2942 Knights of the Round Table 点双连通分量+交叉染色法
- poj 1321 棋盘问题
- 欢迎使用CSDN-markdown编辑器
- tolua++没法用
- spring websocket 使用@SendToUser
- CodeForces 9A Die Roll
- vimrc for debian8
- CodeForces 9B Running Student
- 推荐一些不错的书
- SQL Server 2008 r2出现无法连接到服务器和服务器积极拒绝两个问题
- 【013】【内存调优】
- Maven+Spring+邮件发送
- mysql ICP和MRR性能优化测试