目前的项目是前后端分离的,想在项目里增加对websocket的支持,这件事想做很久了,因为各种原因,一直脱到今天才做.大部分的都还是spring-websocket的,网上例子也很多,需要注意的主要有以下的内容
除了spring一些基础的jar包,还需要引入以下两个
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-websocketartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-messagingartifactId>
<version>${spring.version}version>
dependency>
首先要在web.xml里配置dos
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/dispatcher-servlet.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
<async-supported>trueasync-supported>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
然后在dispatcher-servlet.xml里配置转发规则
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context.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">
<context:component-scan base-package="com.xxx.ws.controller" />
<mvc:annotation-driven />
<mvc:resources mapping="/js/**" location="view/js/"/>
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/wsConnect" >
<websocket:sockjs/>
websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic,/queue"/>
websocket:message-broker>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="rss" value="application/rss+xml" />
map>
property>
<property name="defaultContentType" value="text/html"/>
bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="view/jsp/"/>
<property name="suffix" value=".jsp"/>
bean>
list>
property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
constructor-arg>
bean>
list>
property>
bean>
beans>
@Controller
public class GreetingController
{
private static Logger logger = LoggerFactory.getLogger(GreetingController.class);
@MessageMapping("/wsConnect")//访问wsConnect建立ws连接
@SendTo("/topic/qqq")//订阅/topic/qqq,后,返回信息会往对应的前端推送
public Result addNum(CalcInput input) throws Exception {
logger.debug(input.getNum1()+"+"+input.getNum2()+"="+(input.getNum1()+input.getNum2()));
Thread.sleep(2000);
Result result = new Result(input.getNum1()+"+"+input.getNum2()+"="+(input.getNum1()+input.getNum2()));
return result;
}
}
<html>
<head>
<title>Calculator App Using Spring 4 WebSockettitle>
<script src="/js/sockjs-0.3.4.js">script>
<script src="/js/stomp.js">script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('calculationDiv').style.visibility = connected ? 'visible' : 'hidden';
document.getElementById('calResponse').innerHTML = '';
}
function connect() {
var socket = new SockJS('/websocket/wsConnect');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/qqq', function(calResult){
console.log("22222222222");
showResult(JSON.parse(calResult.body).result);
});
});
}
function disconnect() {
stompClient.disconnect();
setConnected(false);
console.log("Disconnected");
}
function sendNum() {
var num1 = document.getElementById('num1').value;
var num2 = document.getElementById('num2').value;
stompClient.send("/app/wsConnect", {}, JSON.stringify({ 'num1': num1, 'num2': num2 }));
}
function showResult(message) {
var response = document.getElementById('calResponse');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
response.appendChild(p);
}
script>
head>
<body>
<noscript><h2>Enable Java script and reload this page to run Websocket Demoh2>noscript>
<h1>Calculator App Using Spring 4 WebSocketh1>
<div>
<div>
<button id="connect" onclick="connect();">Connectbutton>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnectbutton><br/><br/>
div>
<div id="calculationDiv">
<label>Number One:label><input type="text" id="num1" /><br/>
<label>Number Two:label><input type="text" id="num2" /><br/><br/>
<button id="sendNum" onclick="sendNum();">Send to Addbutton>
<p id="calResponse">p>
div>
div>
body>
html>
apache2.2的版本不支持ws,要使用2.4的版本.安装apache2.4
要支持ws协议,首先要把httpd.conf的LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
注释去掉,启用该模块
然后再配置ws的转发路径
ProxyPass /websocket/wsConnect/info http://localhost:8080/websocket/wsConnect/info
ProxyPass /websocket/ ws://localhost:8080/websocket/