天天看点

我与spring webSocket不得不说的事

作者:it村男主任

Websocket大家都听说过吧,相信大家对他的认识可能更多地的是聊天室,消息等。websocket强大稳定功能多,但我开发的项目只使用了它的部分功能,并且使用的框架是spring,我了解到spring已经整合了websocket,那么项目开发省了很多步骤。不过多说了,我们直接进入主题。等等,为了节省大家时间,我帮大家找了,百科上的介绍是这样的: WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

需求是这样的:

为了达到一个账号一旦登录,那么在其它设备就无法在登陆这个账号,我的方法时登录时向redis中保存该用户主键token,用户点叉号关闭页面或直接关闭浏览器再登录提示该账号已登录中,所以加websocket解决该问题 保证浏览器点叉号关闭浏览器,在登录时不提示账号已登录中。通过websocket实时监测浏览器打开的应用页面关闭或刷新。

1引入websocket

<!--需要引入其他spring包>

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
</dependency>
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
</dependency>           

2编写interceptor拦截器

public class LoginWebsocketInterceptor extends HttpSessionHandshakeInterceptor {
private static final String ALONE_USER_TOKEN = "alone_user_token";
//websocket初次握手之前
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
HttpServletRequest servletRequest
= ((ServletServerHttpRequest) request).getServletRequest();
String token = servletRequest.getParameter("token");
if(StringUtils.isNotBlank(token)){
if(!"null".equals(token)){
//attributes中的值会被放进handler处理器中的webSocketSession中
attributes.put(ALONE_USER_TOKEN,token);
}
}
return super.beforeHandshake(request, response, wsHandler, attributes);
}
//websocket握手之后
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
}           

3编写处理器

public void afterConnectionEstablished(WebSocketSession session) throws Exception {
if(session!=null){
//获取token值
Map<String,Object> attributes = session.getAttributes();
List<Map.Entry<String,Object>> list = Lists.newArrayList();
list.addAll(attributes.entrySet());
//获取指定key的值,也就是前边拦截器中放进attributes中的url上的参数
List<Map.Entry<String, Object>> collect =list.stream().filter(Objects::nonNull).filter(n -> "alone_user_token".equals(n.getKey())).collect(Collectors.toList());
...........
}
}
//连接关闭
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
if(session!=null){
//获取token值
Map<String,Object> attributes = session.getAttributes();
List<Map.Entry<String,Object>> list = Lists.newArrayList();
list.addAll(attributes.entrySet());
List<Map.Entry<String, Object>> collect = list.stream().filter(Objects::nonNull).filter(n -> "alone_user_token".equals(n.getKey())).collect(Collectors.toList());
................
}
}
}           

4配置websocket(xml形式)

allowed-origins="*" 解决跨域问题

我与spring webSocket不得不说的事

5前端页面(那个页面需要连接websocket,就在那个页面添加下边代码)

我与spring webSocket不得不说的事

动动发财的小手给个赞和关注,爱你们哟