spring WebSocket示例详解
场景
websocket是Html5新增加特性之一,目的是浏览器与服务端建立全双工的通信方式,解决http请求-响应带来过多的资源消耗,同时对特殊场景应用提供了全新的实现方式,比如聊天、股票交易、游戏等对对实时性要求较高的行业领域。
背景
在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持;flash中的socket和xmlsocket可以实现真正的双向通信,通过flexajaxbridge,可以在javascript中使用这两项功能.可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。目前各大主流浏览器都支持websocket,IE浏览器要IE10+
一、POM依赖
POM依赖,spring4.1.4.RELEASE,spring核心依赖请自行添加,下面是websocket相关jar
<dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.1.4.RELEASE</version> </dependency>
二、WebSocket入口
@Configuration @EnableWebMvc @EnableWebSocket publicclassWebSocketConfigextendsWebMvcConfigurerAdapterimplementsWebSocketConfigurer{ @Override publicvoidregisterWebSocketHandlers(WebSocketHandlerRegistryregistry){ //允许连接的域,只能以http或https开头 String[]allowsOrigins={"http://www.xxx.com"}; //WebIMWebSocket通道 registry.addHandler(chatWebSocketHandler(),"/webSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor()); registry.addHandler(chatWebSocketHandler(),"/sockjs/webSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor()).withSockJS(); } @Bean publicChatWebSocketHandlerchatWebSocketHandler(){ returnnewChatWebSocketHandler(); } @Bean publicWebSocketHandshakeInterceptormyInterceptor(){ returnnewWebSocketHandshakeInterceptor(); } }
1.实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
2.registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
3.setAllowedOrigins(String[]domains),允许指定的域名或IP(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。如果不限时使用"*"号,如果指定了域名,则必须要以http或https开头。
4.addInterceptors,顾名思义就是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。
5.springwebsocket也支持STOMP协议,下回再分享。
三、拦截器实现
publicclassWebSocketHandshakeInterceptorimplementsHandshakeInterceptor{ @Override publicbooleanbeforeHandshake(ServerHttpRequestrequest,ServerHttpResponseresponse,WebSocketHandlerwsHandler,Map<String,Object >attributes)throwsException{ if(requestinstanceofServletServerHttpRequest){ attributes.put("username",userName); } returntrue; } @Override publicvoidafterHandshake(ServerHttpRequestrequest,ServerHttpResponseresponse,WebSocketHandlerwsHandler,Exceptionexception){ } }
beforeHandshake,在调用handler前处理方法。常用在注册用户信息,绑定WebSocketSession,在handler里根据用户信息获取WebSocketSession发送消息。
四、Handler处理类
publicclassChatWebSocketHandlerextendsTextWebSocketHandler{ privatefinalstaticList<WebSocketSession>sessions=Collections.synchronizedList(newArrayList<WebSocketSession>()); //接收文本消息,并发送出去 @Override protectedvoidhandleTextMessage(WebSocketSessionsession,TextMessagemessage)throwsException{ chatTextMessageHandler(message.getPayload()); super.handleTextMessage(session,message); } //连接建立后处理 @SuppressWarnings("unchecked") @Override publicvoidafterConnectionEstablished(WebSocketSessionsession)throwsException{ logger.debug("connecttothewebsocketchatsuccess......"); sessions.add(session); //处理离线消息 } //抛出异常时处理 @Override publicvoidhandleTransportError(WebSocketSessionsession,Throwableexception)throwsException{ if(session.isOpen()){ session.close(); } logger.debug("websocketchatconnectionclosed......"); sessions.remove(session); } //连接关闭后处理 @Override publicvoidafterConnectionClosed(WebSocketSessionsession,CloseStatuscloseStatus)throwsException{ logger.debug("websocketchatconnectionclosed......"); sessions.remove(session); } @Override publicbooleansupportsPartialMessages(){ returnfalse; } }
五、客户端连接
varhost=window.location.host; varwebsocket; if('WebSocket'inwindow){ websocket=newReconnectingWebSocket("ws://" +host+"/webSocketIMServer",null,{debug:true,maxReconnectAttempts:4}); }elseif('MozWebSocket'inwindow){ websocket=newMozWebSocket("ws://"+host +"/webSocketIMServer"); }else{ websocket=newSockJS("http://"+host +"/sockjs/webSocketIMServer"); } websocket.onopen=function(evnt){ console.log("websocket连接上"); }; websocket.onmessage=function(evnt){ messageHandler(evnt.data); }; websocket.onerror=function(evnt){ console.log("websocket错误"); }; websocket.onclose=function(evnt){ console.log("websocket关闭"); }
这里用到了ReconnectingWebSocket.js,对浏览器自带websocket添加了扩展,例如重连,连接超时时间,失败重连间隔,尝试连接最大次数等。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。