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="*" 解決跨域問題
5前端頁面(那個頁面需要連接配接websocket,就在那個頁面添加下邊代碼)
動動發财的小手給個贊和關注,愛你們喲