webSocket
package com.websocket.socket; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Slf4j @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private MyHandshake handshake; @Autowired private MyHandler handler; /* 配置websocket入口,允许访问的域,注册handler,sockJs支持和拦截器 */ @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) { //注册和路由的功能,当客户端发起websocket链接,把/path交给对应的handler解决,而不实现具体的业务逻辑,是一个收集和任务分发的中心 //setAllowedOrigins(String[] doamins),允许指定的域名或IP建立长连接,如果不限使用,用*表示,如果给定域名,必须以http或者https开头 //addInterceptors,这个就是为handler添加拦截器,可以在调用handler前后加入自己的逻辑代码 webSocketHandlerRegistry.addHandler(handler, "/echo").addInterceptors(handshake).setAllowedOrigins("*"); webSocketHandlerRegistry.addHandler(handler, "/sockjs/echo").addInterceptors(handshake).setAllowedOrigins("*").withSockJS(); } }
1.@Configuration注解标记在项目启动时加载以下配置,一个就是请求进来的拦截器hanshake,一个是请求进来后的处理类handler
$(function () { var websocket; if ('WebSocket' in window) { console.log("WebSocket"); websocket = new WebSocket("ws://localhost:8080/echo"); } else if ('MozWebSocket' in window) { console.log("MozWebSocket"); websocket = new MozWebSocket("ws://echo"); } else { console.log("SockJS"); websocket = new SockJS("http://127.0.0.1:8080/sockjs/echo"); } websocket.onopen = function (evnt) { console.log("链接服务器成功!", evnt.data); }; websocket.onmessage = function (evnt) { console.log('收到消息:', evnt.data); var json = JSON.parse(evnt.data); if (json.hasOwnProperty('users')) { var users = json.users; for (var i = 0; i < users.length; i++) { $("#inputGroupSelect01").append('<option value="' + users[i] + '">' + users[i] + '</option>'); } } else { //打印消息 toast(json.msg, 'info') } };
2:new WebSocket建立websocket的通道,执行时请求会被handshake拦截,
beforeHandshake这个方法中有个map的参数,这个东西其实就是WebSocketSession,我实在没看懂。。。看了源码也没懂为什么这个东西是
WebSocketSession
package com.websocket.socket; import lombok.extern.slf4j.Slf4j; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.stereotype.Service; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; import javax.servlet.http.HttpServletRequest; import java.util.Map; /** *beforeHandshake 握手之前 * afterHandshake 握手之后 */ @Slf4j @Service public class MyHandshake implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception { if (serverHttpRequest instanceof ServletServerHttpRequest) { HttpServletRequest servletRequest = ((ServletServerHttpRequest) serverHttpRequest).getServletRequest(); // 从session中获取到当前登录的用户信息. 作为socket的账号信息. session的的WEBSOCKET_USERNAME信息,在用户打开页面的时候设置. String userName = (String) servletRequest.getSession().getAttribute("WEBSOCKET_USERNAME"); map.put("WEBSOCKET_USERNAME", userName); } return true; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { } }
3:执行完handshake后执行这个hander处理,
String userName = (String) webSocketSession.getAttributes().get("WEBSOCKET_USERNAME");这个东西能get到你在handshake中在map中put的东西。。。因为那个map塞值全塞到
webSocketSession里面了。。。
public class MyHandler implements WebSocketHandler { /** * 为了保存在线用户信息,在方法中新建一个list存储一下【实际项目依据复杂度,可以存储到数据库或者缓存】 */ private final static List<WebSocketSession> SESSIONS = Collections.synchronizedList(new ArrayList<>()); @Override public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception { System.out.println("链接成功......"); SESSIONS.add(webSocketSession); String userName = (String) webSocketSession.getAttributes().get("WEBSOCKET_USERNAME"); if (userName != null) { JSONObject obj = new JSONObject(); // 统计一下当前登录系统的用户有多少个 obj.put("count", SESSIONS.size()); users(obj); webSocketSession.sendMessage(new TextMessage(obj.toJSONString())); } }