spring websocket 使用@SendToUser

spring websocket 使用@SendToUser

Original link: https://blog.csdn.net/yingxiake/article/details/51224569

Before we use @SendTo annotate the method, the return value is converted method messageconverter and pushed to the message broker, the message is broadcast by the agent to the path to subscribe

@MessageMapping ( "bar") // @ MessageMapping receiving the client message
@SendTo ( "/ topic / brocast" ) // @ SendTo broadcast message out
public handle1 Handle that String (String msg) {
return msg;
}

The above will be broadcast to msg "/ topic / brocast" Subscribe to this path, as long as the client subscribed to this path, regardless of which user will receive a message

Then came the demand, if I just want a simple request to the server resources with websocket it, then you put the server resource to me on the line, other users do not you push the broadcast, simply, is my request, you push give me.

spring websocket @SendToUser can be used to do this before using @SendToUser, we need to understand the following:

Establish 1.spring webscoket channel from the beginning or http protocol first handshake after handshake succeeds, will open the browser and the server webscoket by this time, the login authorization information that is javax.security.Principal httprequest It will be bound to the session in websocket

2.spring webscoket can identify with "/ user" and make the subscription process route, for example, if the browser client, a subscription '/ user / topic / greetings' this path,

stompClient.subscribe ( '/ User / Topic / Greetings', function (Data) {
// ...
});

will be spring websocket using UserDestinationMessageHandler be converted to "/ topic / greetings-usererbgz2rq" , "usererbgz2rq" in user keyword, erbgz2rq is sessionid, like this put a unique match up users and subscribers path

3.spring webscoket when using @SendToUser broadcast message,

@MessageMapping ( "handle")
@SendToUser ( "/ Topic / Greetings")
public String handle (String MSG) {
// ...
return MSG;
}
 
"/ Topic / Greetings" is converted into UserDestinationMessageHandler "/ user / role1 / topic / greetings ", role1 is the user's login account, put a message like this only pushed to the requester's subscription to the path, this time, if an account open multiple browser windows, which is more open WebSocket session channel, time, spring webscoket default message will be pushed to a different account of the same session, you can use the broadcast = false pushed to avoid all the session

@MessageMapping ( "handle")
@SendToUser (value = "/ Topic / Greetings", to false = Broadcast)
public String handle (String MSG) {
// ...
return name;
}

below to be a demo, the server is the first to Configuring login authentication authority, where the use of basic security authentication tomcat, configuration of 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 is the login name of the role, which can be configured to verify the information inside the 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"/>



There is both an account, role1 and both, character has role1, password is tomcat, maybe we can use an account to log in IE9 and Google Chrome

 

The server then, we were used @SendTo and @SendToUser broadcast push and push precision

First, we registered under spring webscoket server

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {

// portfolio-stomp is websocket endpoint, the client needs to register the endpoint links, withSockJS allows clients to take advantage of sockjs be browser compatibility processing
registry.addEndpoint ( "/ portfolio-stomp" ) withSockJS ().;

}

@Override
public void configureMessageBroker (MessageBrokerRegistry registry) {
registry.enableSimpleBroker ( "/ Topic"); // set the broadcast message server base path
registry.setApplicationDestinationPrefixes ( "/ app"); // set subscribe messaging client base path
registry .setPathMatcher (new AntPathMatcher () ". "); // can be divided route has to see @messageMapping level and class-level method @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>

到这里就完成了功能了

精准推送

 

 

 

广播推送 

 

Guess you like

Origin www.cnblogs.com/personsiglewine/p/12038300.html