网上关于spring集成websocket的文章都没有涉及通过serverlet启动spring的过程,对于作者这样的小白来说有时候会感到一头雾水,特在此记录一下。
使用maven引入jar包
<properties>
<!-- Spring -->
<spring-framework.version>5.2.1.RELEASE</spring-framework.version>
<!-- Jackson -->
<jackson.version>2.9.10</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- Spring WebSocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
配置web.xml
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 文件编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- welcome file -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
注意:DispatcherServlet是必须配置的,否则无法拦截请求
配置spring-websocket.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/websocket
http://www.springframework.org/schema/websocket/spring-websocket.xsd">
<!--配置 webSocket-->
<bean id="socketHandler" class="com.t.websocket.SocketHandler"/>
<websocket:handlers allowed-origins="file://">
<!--指定 webSocket 地址-->
<websocket:mapping path="/scene/{sn}" handler="socketHandler"/>
</websocket:handlers>
</beans>
注意:allowed-origins用于配置允许的跨域请求
编写handler处理类
package com.t.websocket;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
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;
import com.t.websocket.utils.HttpRequest;
/**
* @desp Socket处理类
* @author hejun
* @date 2016-07-25
*
*/
@Service
public class SocketHandler implements WebSocketHandler{
private static final Logger logger;
static{
logger = LoggerFactory.getLogger(SocketHandler.class);
}
// Websocket连接建立
@Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
logger.info("成功建立Websocket连接");
}
@Override
public void handleMessage(WebSocketSession arg0, WebSocketMessage<?> arg1)
throws Exception {
URI uri = arg0.getUri();
HttpHeaders handshakeHeaders = arg0.getHandshakeHeaders();
logger.info("handshakeHeaders: {}.", handshakeHeaders);
}
// 当连接出错时,主动关闭当前连接,并从会话列表中删除该会话
@Override
public void handleTransportError(WebSocketSession session, Throwable error)
throws Exception {
if(session.isOpen()){
session.close();
}
logger.error("连接出现错误:"+error.toString());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus arg1)
throws Exception {
logger.debug("Websocket连接已关闭");
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 发送命令
*
* @param commandMap
* @throws IOException
*/
public void sendCommand(Map<String, String> sns) throws IOException {
WebSocketSession session = sns.get(sn);
if(session == null) {
logger.error("The scene [{}] WebSocketSession is not exists. The device may doesn't online.", sn);
throw new RuntimeException("The WebSocketSession is null!");
}
if(!session.isOpen()) {
logger.error("The scene [{}] WebSocketSession has closed.", sn);
throw new RuntimeException("The WebSocketSession has closed!");
}
session.sendMessage(new TextMessage(command));
}
}