AI智能
改变未来

spring中使用webSocket


WebSocket介绍

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

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

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

协议有两部分,握手和数据传输。
握手是基于http协议的
来自客户端的握手形式如下:

来自服务器的握手形式如下:

字段说明:

客户端实现

websocket对象
实现 WebSockets 的 Web 通过WebSocket 对象公开所有的必需的客户端功能。
以下 API 用于创建 WebSocket 对象:

var ws = new WebSocket(url);//参数url格式说明: ws://ip地址端口号/资源名称


websocket方法

引入POM依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId><version>4.2.4.RELEASE</version></dependency>

WebSocket入口配置

@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {/*** 注册handle* @see org.springframework.web.socket.config.annotation.WebSocketConfigurer#registerWebSocketHandlers(org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry)*/@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegis20000try registry) {registry.addHandler(myHandler(), "/testHandler.do").addInterceptors(new WebSocketInterceptor());registry.addHandler(myHandler(), "/socketJs/testHandler.do").addInterceptors(new WebSocketInterceptor()).withSockJS();}@Beanpublic WebSocketHandler myHandler(){return new MyMessageHandler();}}
  1. 实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
  2. registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
  3. addInterceptors,是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。

创建拦截器

public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {@Overridepublic boolean beforeHandshake(ServerHttpRequest request,ServerHttpResponse response, WebSocketHandler wsHandler,Map<String, Object> attributes) throws Exception {if (request instanceof ServletServerHttpRequest) {ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;// 获取参数String userId = serverHttpRequest.getServletRequest().getParameter("userId");attributes.put("currentUser", userId);}return true;}// 初次握手访问后@Overridepublic void afterHandshake(ServerHttpRequest serverHttpRequest,ServerHttpResponse serverHttpResponse,WebSocketHandler webSocketHandler, Exception e) {}}

beforeHandshake,在调用handler前处理方法。常用在登录用户信息,绑定WebSocketSession,在handler里根据用户信息获取WebSocketSession发送消息。

Handler处理类

public class MyMessageHandler implements WebSocketHandler {/*** userMap:使用线程安全map存储用户连接webscoket信息** @since JDK 1.7*/private final static Map<String, WebSocketSession> userMap = new new ConcurrentHashMap<String, WebSocketSession>();/*** 关闭websocket时调用该方法** @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession,*      org.springframework.web.socket.CloseStatus)*/@Overridepublic void afterConnectionClosed(WebSocketSession session,CloseStatus status) throws Exception {String userId = this.getUserId(session);if (StringUtils.isNoneBlank(userId)) {userMap.remove(userId);System.err.println("该" + userId + "用户已成功关闭");} else {System.err.println("关闭时,获取用户id为空");}}/*** 建立websocket连接时调用该方法**  org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)*/@Overridepublic void afterConnectionEstablished(WebSocketSession session)throws Exception {String userId = this.getUserId(session);if (StringUtils.isNoneBlank(userId)) {userMap.put(userId, session);session.sendMessage(new TextMessage("建立服务端连接成功!"));}}/*** 客户端调用websocket.send时候,会调用该方法,进行数据通信** org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession,*      org.springframework.web.socket.WebSocketMessage)*/@Overridepublic void handleMessage(WebSocketSession session,WebSocketMessage<?> message) throws Exception {}/*** 传输过程出现异常时,调用该方法** org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession,*      java.lang.Throwable)*/@Overridepublic void handleTransportError(WebSocketSession session, Throwable e)throws Exception {WebSocketMessage<String> message = new TextMessage("异常信息:"+ e.getMessage());session.sendMessage(message);}/****   org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()*/@Overridepublic boolean supportsPartialMessages() {return false;}/*** sendMessageToUser:发给指定用户**/public void sendMessageToUser(String userId, String contents) {WebSocketSession session = userMap.get(userId);if (session != null && session.isOpen()) {try {TextMessage message = new TextMessage(contents);session.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}/*** sendMessageToAllUsers:发给所有的用户**/public void sendMessageToAllUsers(String contents) {Set<String> userIds = userMap.keySet();for (String userId : userIds) {this.sendMessageToUser(userId, contents);}}/*** getUserId:获取用户id** @author liuchao* @param session* @return* @since JDK 1.7*/private String getUserId(WebSocketSession session) {try {String userId = (String) session.getAttributes().get("currentUser");return userId;} catch (Exception e) {e.printStackTrace();}return null;}

客户端连接

<script type="text/javascript">$(function(){var host= window.location.host;var websocket;if ('WebSocket' in window) {websocket = new WebSocket("ws://"+host+"/testHandler.do?userId=9528");} else if ('MozWebSocket' in window) {websocket = new MozWebSocket("ws://"+host+"/testHandler.do?userId=9528");} else {websocket = new SockJS("http://"+host+"/socketJs/testHandler.do?userId=9528");}websocket.onopen = function (evnt) {console.log("链接服务器成功!")};websocket.onmessage = function (evnt) {console.log(evnt.data);$("#message").html(evnt.data);};websocket.onerror = function (evnt) {console.log("websocket错误");};websocket.onclose = function (evnt) {console.log("与服务器断开了链接!")}$('#send').bind('click', function() {send();});function send(){if (websocket != null) {var message = document.getElementById('message').value;websocket.send(message);} else {alert('未与服务器链接.');}}});</script>
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » spring中使用webSocket