标签:
实现的版本jdk1.7.0_25, tomcat7.0.47.0, Tengine/2.1.1 (nginx/1.6.2), servlet3.0, spring4.2.2
使用maven导入版本3.0+的servlet包:
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3.0-alpha-1</version> </dependency>
然后配置web.xml将版本的xsi配置在3.0以上:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
导入spring web socket包:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.2.2.RELEASE</version> </dependency>
在spirng的DispatcherServlet的配置文件配置spring websocket handler:
<websocket:handlers allowed-origins="*"> <websocket:mapping path="/outer/notice/listen" handler="noticeMessageHandler"/> <websocket:handshake-interceptors> <bean class="com.j.socket.notice.NoticeMessageInterceptor"/> </websocket:handshake-interceptors> </websocket:handlers> <websocket:handlers allowed-origins="*"> <websocket:mapping path="/outer/notice/sockjs/listen" handler="noticeMessageHandler"/> <websocket:handshake-interceptors> <bean class="com.j.socket.notice.NoticeMessageInterceptor"/> </websocket:handshake-interceptors> <websocket:sockjs/> </websocket:handlers>
配置handler class:
package com.j.socket.notice.NoticeMessageHandler;
// import packages
@Component public class NoticeMessageHandler implements WebSocketHandler { //存储当前所有的在线用户socket //目前以userId为key,所以一个用户打开多个socket页面时只会在最新的页面推送消息 private static final Map<String, WebSocketSession> users = new HashMap<>(); //socket 连接常见时该方法被调用 @Override public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception { //在socket Interceptor中设置的参数 String userId = webSocketSession.getAttributes().get("SOCKET_USER"); users.put(userId, webSocketSession); } @Override public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception { //前端发送消息时调用该方法 } //连接出错时 @Override public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception { if (webSocketSession.isOpen()) { webSocketSession.close(); } String userId = webSocketSession.getAttributes().get("SOCKET_USER"); users.remove(userId); } //连接关闭时 @Override public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception { String userId = webSocketSession.getAttributes().get("SOCKET_USER"); users.remove(userId); } @Override public boolean supportsPartialMessages() { return false; } //向某个用户发送消息 public void sendMessage(TextMessage message, String userId) { WebSocketSession user = users.get(userId); if (null != user && user.isOpen()) { try { user.sendMessage(message); } catch (Exception e) { } } } //批量向所有用户发送消息 public void sendMessage(TextMessage message) { for (WebSocketSession user : users.values()) { if (user.isOpen()) { try { user.sendMessage(message); } catch (Exception e) { } } } } }
配置拦截器,在websocket链接时从请求中获取用户数据,并存储起来。
public class NoticeMessageInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception { if (serverHttpRequest instanceof ServletServerHttpRequest) { ServletServerHttpRequest request = (ServletServerHttpRequest) serverHttpRequest; String userId = request.getServletRequest().getParameter("userId"); if (StringUtils.isNotBlank(userId)) { map.put(Constants.SOCKET_USER, userId); return true; } } return false; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { } }
前端js代码,如果浏览器不支持socket时将使用sockJS 所以需要根据情况导入sockJS文件
var websocket; if (‘WebSocket‘ in window) { websocket = new WebSocket("ws://yoururl.com/outer/notice/listen?userId="+ getUserId()); } else if (‘MozWebSocket‘ in window) { websocket = new MozWebSocket("ws://yoururl.com/outer/notice/listen?userId="+getUserId()); } else { websocket = new SockJS("http://yoururl.com/outer/notice/sockjs/listen?userId="+getUserId()); } websocket.onopen = function (evnt) { }; var length = 0 ; websocket.onmessage = function (evnt) { console.log(length+=evnt.data.length); }; websocket.onerror = function (evnt) { console.log(evnt); }; websocket.onclose = function (evnt) { }
nginx相应配置
map $http_upgrade $connection_upgrade { default upgrade; ‘‘ close; } server { ... location ~* /(outer/notice)|(outer/sockjs/notice)/ { proxy_pass http://127.0.0.1:8084; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
标签:
原文地址:http://www.cnblogs.com/whataya/p/4929344.html