Spring与WebSocket的整合
2016-01-19 22:48
483 查看
1 环境
jdk1.8tomcat 7
spring4.0.5
2 pom.xml的配置
2.1 引入Spring相关的配置
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.0.5.RELEASE</spring.version> </properties> <dependencies> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
2.2 websocket相关的配置
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.0.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>4.0.5.RELEASE</version> </dependency>
3 编写WebSocketConfig、HandshakeInterceptor与WebSocketHander
3.1 WebSocketConfig
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebMvc @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { /** * 支持websocket 的 connection */ registry.addHandler(new WebSocketHander(),"/websocket").addInterceptors(new HandshakeInterceptor()); /** * 不支持websocket的connenction,采用sockjs */ registry.addHandler(new WebSocketHander(),"/sockjs/websocket").addInterceptors(new HandshakeInterceptor()).withSockJS(); } }
3.2 HandshakeInterceptor
import java.util.Map; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.WebSocketHandler; public class HandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor { /** * Interceptor before hander */ @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception { return true; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { } }
3.3 WebSocketHander
import java.io.IOException; import java.util.ArrayList; import javax.annotation.Resource; import org.slf4j.Logger; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; public class WebSocketHander implements WebSocketHandler { private static final Logger logger = org.slf4j.LoggerFactory.getLogger(WebSocketHander.class); private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>(); /** * after connection establish */ public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.info("connect success..."); users.add(session); } /** * process the received message */ @Override public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception { sendMessageToUsers(new TextMessage(webSocketMessage.getPayload() + "hello")); } @Override public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception { if(webSocketSession.isOpen()){ webSocketSession.close(); } logger.info("connenction error,close the connection..."); users.remove(webSocketSession); } @Override public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception { logger.info("close the connenction..."+closeStatus.toString()); users.remove(webSocketSession); } @Override public boolean supportsPartialMessages() { return false; } /** * 给所有在线用户发送消息 * * @param message */ public void sendMessageToUsers(TextMessage message) { for (WebSocketSession user : users) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } } }}
<span style="font-weight: normal;"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head lang="en"> <meta charset="UTF-8"> <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"> <!-- 可选的Bootstrap主题文件(一般不用引入) --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"> <!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> <script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> <!--<script type="text/javascript" src="js/jquery-1.7.2.js"></script>--> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <title>webSocket测试</title> <script type="text/javascript"> $(function(){ var websocket; if ('WebSocket' in window) { alert("WebSocket"); websocket = new WebSocket("ws://localhost:8080/项目名称/websocket"); } else if ('MozWebSocket' in window) { alert("MozWebSocket"); websocket = new MozWebSocket("ws://echo"); } else { alert("SockJS"); websocket = new SockJS("http://localhost:8080/<span style="font-family: Arial, Helvetica, sans-serif;">项目名称</span><span style="font-family: Arial, Helvetica, sans-serif;">/sockjs/websocket");</span> } websocket.onopen = function (evnt) { $("#tou").html("链接服务器成功!") }; websocket.onmessage = function (evnt) { $("#msg").html($("#msg").html() + "<br/>" + evnt.data); }; websocket.onerror = function (evnt) { }; websocket.onclose = function (evnt) { $("#tou").html("与服务器断开了链接!") } $('#send').bind('click', function() { send(); }); function send(){ if (websocket != null) { var message = document.getElementById('message').value; websocket.send(message); } else { alert('未与服务器链接.'); } } }); </script> </head> <body> <div class="page-header" id="tou"> webSocket及时聊天Demo程序 </div> <div class="well" id="msg"> </div> <div class="col-lg"> <div class="input-group"> <input type="text" class="form-control" placeholder="发送信息..." id="message"> <span class="input-group-btn"> <button class="btn btn-default" type="button" id="send" >发送</button> </span> </div><!-- /input-group --> </div><!-- /.col-lg-6 --> </div><!-- /.row --> </body> </html></span>现象:输入字符,服务器对输入的字符加上“hello”返回!
5. 错误
5.1Async support must be enabled on a servlet and for all filters involved in async request processing
如果直接运行,基本上会包上面的错误,我们还需要在web.xml中做如下的配置
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">[/code]然后在这个servlet中加入:<async-supported>true</async-supported>如下:<servlet> <servlet-name>presto-engine</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:presto_servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet>同时在各个filter也要加入async-supported
5.2 The extension [x-webkit-deflate-frame] is not supported
在HandshakeInterceptor的beforeHandshake方法中加入<span style="font-size:10px;font-weight: normal;">@Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception { /** * This is a bug,bug fix:The extension [x-webkit-deflate-frame] is not supported */ if(request.getHeaders().containsKey("Sec-WebSocket-Extensions")) { request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate"); } return true; }</span>
相关文章推荐
- 如何在Spring中集成Hessian框架
- Spring对Hibernate事务管理【转】
- Java中的异常详解
- Java基础-------数据类型
- spring自定义注解
- JDK安装及环境变量配置(windows7)
- [Struts 2系列] Struts 2发展历程
- JAVA类的初始化顺序
- 多版本JDK配置问题
- JAVA多线程学习之ReentrantReadWriteLock
- Java 开源软件测试工具
- Spring的容器配置文件问题
- 使用Java 随机读写文件RandomAccessFile类和String类遇到的问题
- Set up eclipse for Ext js and spket IDE plugin
- Java程序性能优化技巧
- eclipse 快捷键2
- Java垃圾回收机制
- Java拼接字符串时,去掉最后一个多余的逗号
- Java拼接字符串时,去掉最后一个多余的逗号
- Java拼接字符串时,去掉最后一个多余的逗号