您的位置:首页 > 编程语言 > Java开发

利用spring-websocket包搭建websocket服务

2017-10-12 21:34 337 查看
折腾了将近一天,终于搭建好websocket服务,中间遇到不少的坑,现在记录一下,也供他们参考少走弯路。

开发环境:<spring.version>4.2.5.RELEASE</spring.version> Tomcat8 jdk8 maven

spring搭建websocket有两种方式:

1、利用javaee-api以注解的形式搭建,见上一篇博文《spring+tomcat8实现websocket 》

2、利用spring-websocket包搭建,本篇介绍的内容。

注意:这种方式必须注释掉这个,不然会冲突

<!-- <dependency>

<groupId>javax</groupId>

<artifactId>javaee-api</artifactId>

<version>7.0</version>

</dependency> -->

需要用到的spring包:

<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>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>

Java代码:两个类 WebSocketConfig 和 SystemWebSocketHandler

[java] view
plain copy

@Configuration

@EnableWebMvc

@EnableWebSocket

public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

registry.addHandler(systemWebSocketHandler(),"/webSocketServer");

registry.addHandler(systemWebSocketHandler(),"/webSocketServer/sockjs").setAllowedOrigins("*").withSockJS();

//registry.addHandler(systemWebSocketHandler(),"/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor());

//registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new WebSocketHandshakeInterceptor()).withSockJS();

//registry.addHandler(systemWebSocketHandler(), "/webSocketServer/sockjs").withSockJS();

/*registry.addHandler(systemWebSocketHandler(),"/ws").addInterceptors(new WebSocketHandshakeInterceptor());

registry.addHandler(systemWebSocketHandler(), "/ws/sockjs").addInterceptors(new WebSocketHandshakeInterceptor())

.withSockJS();*/

}

@Bean

public WebSocketHandler systemWebSocketHandler(){

return new SystemWebSocketHandler();

}

[java] view
plain copy

import java.io.IOException;

import java.util.ArrayList;

import java.util.Date;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.messaging.Message;

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.mspj.frame.core.web.controller.BaseWebControllerImpl;

public class SystemWebSocketHandler implements WebSocketHandler {

private Logger log = LoggerFactory.getLogger(SystemWebSocketHandler.class);

private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();;

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

System.out.println("ConnectionEstablished");

log.debug("ConnectionEstablished");

users.add(session);

session.sendMessage(new TextMessage("connect"));

session.sendMessage(new TextMessage("new_msg"));

}

@Override

public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {

System.out.println("handleMessage" + message.toString());

log.debug("handleMessage" + message.toString());

//sendMessageToUsers();

session.sendMessage(new TextMessage(new Date() + ""));

}

@Override

public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

if(session.isOpen()){

session.close();

}

users.remove(session);

log.debug("handleTransportError" + exception.getMessage());

}

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {

users.remove(session);

log.debug("afterConnectionClosed" + closeStatus.getReason());

}

@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();

}

}

}

}

前端调式页面代码

[html] view
plain copy

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>WebSocket/SockJS Echo Sample (Adapted from Tomcat's echo sample)</title>

<style type="text/css">

#connect-container {

float: left;

width: 400px

}

#connect-container div {

padding: 5px;

}

#console-container {

float: left;

margin-left: 15px;

width: 400px;

}

#console {

border: 1px solid #CCCCCC;

border-right-color: #999999;

border-bottom-color: #999999;

height: 170px;

overflow-y: scroll;

padding: 5px;

width: 100%;

}

#console p {

padding: 0;

margin: 0;

}

</style>

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>

<script type="text/javascript">

var ws = null;

var url = null;

var transports = [];

function setConnected(connected) {

document.getElementById('connect').disabled = connected;

document.getElementById('disconnect').disabled = !connected;

document.getElementById('echo').disabled = !connected;

}

function connect() {

if (!url) {

alert('Select whether to use W3C WebSocket or SockJS');

return;

}

//ws = new WebSocket('ws://192.168.10.107:8080/mspjapi/webSocketServer');/* (url.indexOf('sockjs') != -1) ?

//new SockJS(url, undefined, {protocols_whitelist: transports}) : */

ws = new SockJS("http://192.168.10.107:8080/mspjapi/webSocketServer/sockjs");

//console.log("http://192.168.10.107:8080/mspjapi/webSocketServer/sockjs");

ws.onopen = function () {

setConnected(true);

log('Info: connection opened.');

};

ws.onmessage = function (event) {

log('Received: ' + event.data);

};

ws.onclose = function (event) {

setConnected(false);

log('Info: connection closed.');

log(event);

};

}

function disconnect() {

if (ws != null) {

ws.close();

ws = null;

}

setConnected(false);

}

function echo() {

if (ws != null) {

var message = document.getElementById('message').value;

log('Sent: ' + message);

ws.send(message);

} else {

alert('connection not established, please connect.');

}

}

function updateUrl(urlPath) {

if (urlPath.indexOf('sockjs') != -1) {

url = urlPath;

document.getElementById('sockJsTransportSelect').style.visibility = 'visible';

}

else {

if (window.location.protocol == 'http:') {

url = 'ws://' + window.location.host + urlPath;

} else {

url = 'wss://' + window.location.host + urlPath;

}

document.getElementById('sockJsTransportSelect').style.visibility = 'hidden';

}

}

function updateTransport(transport) {

transports = (transport == 'all') ? [] : [transport];

}

function log(message) {

var console = document.getElementById('console');

var p = document.createElement('p');

p.style.wordWrap = 'break-word';

p.appendChild(document.createTextNode(message));

console.appendChild(p);

while (console.childNodes.length > 25) {

console.removeChild(console.firstChild);

}

console.scrollTop = console.scrollHeight;

}

</script>

</head>

<body>

<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets

rely on Javascript being enabled. Please enable

Javascript and reload this page!</h2></noscript>

<div>

<div id="connect-container">

<input id="radio1" type="radio" name="group1" onclick="updateUrl('/mspjapi');">

<label for="radio1">W3C WebSocket</label>

<br>

<input id="radio2" type="radio" name="group1" onclick="updateUrl('/spring-websocket-test/sockjs/echo');">

<label for="radio2">SockJS</label>

<div id="sockJsTransportSelect" style="visibility:hidden;">

<span>SockJS transport:</span>

<select onchange="updateTransport(this.value)">

<option value="all">all</option>

<option value="websocket">websocket</option>

<option value="xhr-polling">xhr-polling</option>

<option value="jsonp-polling">jsonp-polling</option>

<option value="xhr-streaming">xhr-streaming</option>

<option value="iframe-eventsource">iframe-eventsource</option>

<option value="iframe-htmlfile">iframe-htmlfile</option>

</select>

</div>

<div>

<button id="connect" onclick="connect();">Connect</button>

<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>

</div>

<div>

<textarea id="message" style="width: 350px">Here is a message!</textarea>

</div>

<div>

<button id="echo" onclick="echo();" disabled="disabled">Echo message</button>

</div>

</div>

<div id="console-container">

<div id="console"></div>

</div>

</div>

<a href="echoendpoint.jsp">echoendpoint test</a>

<a href="websocket2.jsp">echoendpoint test</a>

</body>

</html>

最后说下几个坑点:

1、html页面访问限制的问题的:403 Forbidden

[java] view
plain copy

registry.addHandler(systemWebSocketHandler(),"/webSocketServer/sockjs").setAllowedOrigins("*").withSockJS();

2、web.xml配置需要升级成3.1

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">

3、web.xml里面所有过滤器需要加上

<async-supported>true</async-supported>

如:

<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-mvc.xml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

<async-supported>true</async-supported>

</servlet>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: