在SpringMVC中使用WebSocket

2/10/2017来源:ASP.NET技巧人气:1071

SPRingMvc项目的搭建在这里就不做多解释,要在Spring中实现 WebSocket 必须加上 spring-websocket和 spring-messaging两个包,同样,完整的pom.xml给出如下: <project xmlns="http://maven.apache.org/POM/4.0.0"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0     http://maven.apache.org/maven-v4_0_0.xsd">     <modelVersion>4.0.0</modelVersion>     <groupId>com.656463</groupId>     <artifactId>demo-websocket</artifactId>     <packaging>war</packaging>     <name>demo-websocket Maven Webapp</name>     <version>0.0.1-SNAPSHOT</version>     <url>http://maven.apache.org</url>     <properties>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>         <spring.version>4.1.6.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-core</artifactId>             <version>${spring.version}</version>         </dependency>         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-beans</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-jdbc</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-websocket</artifactId>             <version>${spring.version}</version>         </dependency>         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-messaging</artifactId>             <version>${spring.version}</version>         </dependency>         <dependency>             <groupId>org.aspectj</groupId>             <artifactId>aspectjweaver</artifactId>             <version>1.7.4</version>         </dependency>         <dependency>             <groupId>com.google.code.gson</groupId>             <artifactId>gson</artifactId>             <version>2.7</version>         </dependency>         <dependency>             <groupId>jstl</groupId>             <artifactId>jstl</artifactId>             <version>1.2</version>         </dependency>         <dependency>             <groupId>taglibs</groupId>             <artifactId>standard</artifactId>             <version>1.1.2</version>         </dependency>         <dependency>             <groupId>javax.websocket</groupId>             <artifactId>javax.websocket-api</artifactId>             <version>1.1</version>             <scope>provided</scope>         </dependency>         <dependency>             <groupId>javax</groupId>             <artifactId>javaee-api</artifactId>             <version>7.0</version>             <scope>provided</scope>         </dependency>     </dependencies>     <build>         <finalName>demo-websocket</finalName>         <plugins>             <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-compiler-plugin</artifactId>                 <version>3.0</version>                 <configuration>                     <source>1.7</source>                     <target>1.7</target>                 </configuration>             </plugin>             <plugin>                 <groupId>org.apache.tomcat.maven</groupId>                 <artifactId>tomcat7-maven-plugin</artifactId>                 <version>2.2</version>                 <configuration>                     <port>8080</port>                     <path>/</path>                 </configuration>             </plugin>         </plugins>     </build> </project> 定义一个简单的WebSocket客户端页面,这里只有一个连接和发送消息的功能,这个示例和上个示例的功能类似 <%@ page language="java" contentType="text/html; charset=UTF-8"          pageEncoding="UTF-8" %> <!DOCTYPE html> <html lang="en"> <head>     <meta charset="utf-8">     <title></title>     <script type="text/Javascript" src="/static/js/jquery-1.9.1.js"></script>     <script type="text/javascript">         $(function () {             var websocket;             var target = "ws://192.168.56.101:8080/hello.htm";             if ('WebSocket' in window) {                 websocket = new WebSocket(target);             } else if ('MozWebSocket' in window) {                 websocket = new MozWebSocket(target);             } else {                 alert('WebSocket is not supported by this browser.');                 return;             }             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 id="tou"> webSocket及时聊天Demo程序</div> <div id="msg"></div> <input type="text" id="message"> <button type="button" id="send"> 发送</button> </body> </html> 创建握手拦截器的类 HandInterceptor ,此类实现 HandshakeInterceptor接口。此类的功能有点类似于使用原始J2EE实现的@OnOpen注解 package com._656463.demo.websocket.spring; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; import javax.servlet.http.HttpServletRequest; import java.util.Map; /**  * 拦截器(握手)  */ public class HandInterceptor implements HandshakeInterceptor {     @Override     public boolean beforeHandshake(ServerHttpRequest request,             ServerHttpResponse response, WebSocketHandler handler,             Map<String, Object> map) throws Exception {         if (request instanceof ServletServerHttpRequest) {             HttpServletRequest req = ((ServletServerHttpRequest) request).getServletRequest();             String userName = "default-user";             // 使用userName区分WebSocketHandler,以便定向发送消息             // String userName = (String)             // session.getAttribute("WEBSOCKET_USERNAME");             map.put("WEBSOCKET_USERNAME", userName);             req.getSession().setAttribute("WEBSOCKET_USERNAME", userName);         }         return true;     }     @Override     public void afterHandshake(ServerHttpRequest serverHttpRequest,             ServerHttpResponse serverHttpResponse,             WebSocketHandler webSocketHandler, Exception e) {     } } 创建一个类 WebSocketHander,实现 WebSocketHandler接口,此类的主要功能是消息处理中心,相当于使用原始J2EE API实现中的@OnMessage和@OnClose注解功能 package com._656463.demo.websocket.spring; import org.springframework.web.socket.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; /**  * 消息处理中心  */ public class WebSocketHander implements WebSocketHandler {     private static final List<WebSocketSession> users = new ArrayList<WebSocketSession>();     /**      * 初次链接成功执行      *      * @param session      * @throws Exception      */     @Override     public void afterConnectionEstablished(WebSocketSession session) throws Exception {         System.out.println("链接成功......");         users.add(session);         String userName = (String) session.getAttributes().get("WEBSOCKET_USERNAME");         if (userName != null) {             //查询未读消息             int count = 5;             session.sendMessage(new TextMessage(count + ""));         }     }     /**      * 接受消息处理消息      *      * @param session      * @param message      * @throws Exception      */     @Override     public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {         sendMessageToUsers(new TextMessage(message.getPayload() + ""));     }     @Override     public void handleTransportError(WebSocketSession session, Throwable throwable) throws Exception {         if (session.isOpen()) {             session.close();         }         System.out.println("链接出错,关闭链接......");         users.remove(session);     }     @Override     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {         System.out.println("链接关闭......" + status.toString());         users.remove(session);     }     @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();             }         }     }     /**      * 给某个用户发送消息      *      * @param userName      * @param message      */     public void sendMessageToUser(String userName, TextMessage message) {         for (WebSocketSession user : users) {             if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) {                 try {                     if (user.isOpen()) {                         user.sendMessage(message);                     }                 } catch (IOException e) {                     e.printStackTrace();                 }                 break;             }         }     } } 有了握手拦截器和消息处理中心之后,要开启WebSocket,让他工作起来。 开启WebSocket有两种方式,一种是基于注解的方式,二是基本XML配置的方式  1、基于注解的方式 在springmvc的配置文件中,配置扫描包 <!-- websocket相关扫描,主要扫描:WebSocketConfig.java 这个类路径 --> <context:component-scan base-package="com._656463.demo.websocket.spring"/> 创建WebSocketConfig,开启WebSocket,并注册WebSocket的请求路径 package com._656463.demo.websocket.spring; 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; /**  * EnableWebSocket 开启websocket  *  * @EnableWebMvc //这个标注可以不加,如果有加,要extends WebMvcConfigurerAdapter  */ @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer {     @Override     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {         // 支持websocket 的访问链接         registry.addHandler(new WebSocketHander(), "/hello.htm")                 .addInterceptors(new HandInterceptor());         // 不支持websocket的访问链接         registry.addHandler(new WebSocketHander(), "/sockjs/hello.htm")                 .addInterceptors(new HandInterceptor())                 .withSockJS();     } } 2、基于XML配置的方式 在springmvc的配置文件中,通过websocket标签配置WebSocket <!-- 可以在这里配置websocket的相关类,也可以用注解,详细可以查看com._656463.demo.websocket.spring.WebSocketConfig --> <bean id="websocket" class="com._656463.demo.websocket.spring.WebSocketHander"/> <websocket:handlers>     <websocket:mapping path="/hello.htm" handler="websocket" />     <websocket:handshake-interceptors>         <bean class="com._656463.demo.websocket.spring.HandInterceptor"/>     </websocket:handshake-interceptors> </websocket:handlers> 本次基于Springmvc的WebSocket实例就讲完了,本实例是书生参考网络整理的,希望对你有所帮助