SpringMVC WebSocket Apache代理 相关技术点总结
来源:互联网 发布:微信分销源码下载 编辑:程序博客网 时间:2024/09/21 06:35
SpringMVC + WebSocket这个技术的文章一大把,最后笔者发现对WebSocket一知半解的情况下使用这个技术,任然会存在问题,有时还会觉得莫名其妙,而且在直接使用别人代码的情况下更是如此。本文希望通过本篇文章介绍一下个人经验总结。
如果英语尚可,直接参考SpringMVC官方对WebSocket的支持文档,点击这里
WebSocket
这个技术不神秘,而且简单易用,只需要使用@ServerEndpoint注解一个类即可,再使用@OnMessage, @OnOpen, @OnClose注解一下方法,实现对WebSocket的管理和消息处理。需要Tomcat 7.0以上。
客户端,使用WebSocket实现访问。
参考资料:JSR-356标准, TOMCAT 7.0 以上是支持该标准的。
ServerEndPoint文档点击这里
下面就一步步的通过Eclipse+Tomcat实现WebSocket通讯,建议新手像我一样先试试。
自己动手创建第一个WebSocket
- Eclipse建立Web 3.0的项目(Eclipse4.5.1)
- 编写WebSocket服务端代码
@ServerEndpoint("/hello")public class HelloServer { @OnMessage public String processGreeting(String message, Session session) { System.out.println("Greeting received:" + message); return "Server echo:" + message + " at " + Calendar.getInstance().getTime().toString(); }}
上述代码参考了前面JSR-356的标准文档,ServerEndPoint文档,稍做修改,使用了带返回值的OnMessage注解的方法,这样就可以实现和前端通讯。
- 编写HTML测试代码
test/jsr356.html
<!DOCTYPE html><html><head><title>Testing websockets using JSR-356</title><script type="text/javascript"> var webSocket = new WebSocket('ws://localhost:9090/TestWebSocket/hello'); webSocket.onerror = function(e){onError(e)}; webSocket.onopen = function(e) {onOpen(e)}; webSocket.onmessage = function(e) {onMessage(e)}; function onMessage(event) { document.getElementById('messages').innerHTML += '<br />' + event.data; } function onOpen(event) { document.getElementById('messages').innerHTML = 'Connection established'; } function onError(e) {alert(e.data);} function startWebSocket() { webSocket.send('hello'); return false; }</script></head><body> <div> <input type="submit" value="Start" onclick="startWebSocket()" /> </div> <div id="messages"></div></body></html>
以上代码需要修改的地方只有:WebSocket对象建立时指定的WEB服务器名称,端口,虚拟目录名称。笔者为本机9090, 项目名称为TestWebSocket, hello为websocket服务端口URL。
http://localhost:9090/TestWebSocket/test/jsr356.html
小结
以上代码就是简要使用TOMCAT直接支持的方法和浏览器一同实现了WebSocket通讯,客户端提交hello消息,会从服务端就收消息。好像和一般的请求没啥区别啊!是啊!没有区别!Web请求,实现一个数据请求,就可以返回数据啊!WebSocket的关键在于,他的通讯是在水下面发生的,通过浏览器的工具没有办法直接查看WebSocket的数据报文,这是第一点,另外一点就是可以实现相互通讯,即通过服务器就可以直接和在线的客户端通讯,解决了以前客户端只能通过轮询实现数据更新。在JS4-356标准种,@OnOpen可以获得新打开的会话,从而实现和浏览器的关联,并可以实现服务器向客户端直接通讯。
下面是WebSocket在浏览器工具中看到的通讯过程:
注意:WebSocket对象 IE 9以下不支持……“WebSocket”未定义
MAVEN项目需要包含如下依赖,以便让TOMCAT使用新版本的javeee api.
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope></dependency>
SpringMVC + WebSocket
参考文献:WebSocket Support
通过SpringMVC实现WebSocket好处多多,具体请看英文文档,主要是解决了协议兼容的问题。
使用SpringMVC需要的库有好几个,本文示例,就直接通过普通J2EE项目搭建示例,建议项目中采用maven或其他管理依赖。
本示例需要用到jar包:
commons-logging-1.2.jar; spring-aop-4.2.5.RELEASE.jar; spring-beans-4.2.5.RELEASE.jar; spring-context-4.2.5.RELEASE.jar; spring-context-support-4.2.5.RELEASE.jar; spring-core-4.2.5.RELEASE.jar; spring-expression-4.2.5.RELEASE.jar; spring-web-4.2.5.RELEASE.jar; spring-webmvc-4.2.5.RELEASE.jar; spring-websocket-4.2.5.RELEASE.jar.
实现WebSocket + SpringMVC的基本处理类:
test.websocket.MyHandler.java
package test.websocket;import java.io.IOException;import java.util.Calendar;import org.springframework.web.socket.TextMessage;import org.springframework.web.socket.WebSocketSession;import org.springframework.web.socket.handler.TextWebSocketHandler;public class MyHandler extends TextWebSocketHandler{ public MyHandler(){ super(); System.out.println("MyHandler constractor..."); } @Override public void handleTextMessage(WebSocketSession session, TextMessage message) { System.out.println("Client received:" + message.getPayload()); try { session.sendMessage(new TextMessage("Server echo:" + message.getPayload() + " at " + Calendar.getInstance().getTime().toString())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
通过注解实现WebSocket的配置类(直接用注解实现初始化):
test.websocket.WebSocketConfig
package test.websocket;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.WebSocketHandler;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@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/myHandler"); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); }}
有两种方式通过Spring初始化WebSocket.
- 通过注解的方式(@EnableWebSocket)
- 通过XML配置文件的方式(websocket:handlers)
无论是通过上述哪种方式,都需要配置Spring.
- 在web.xml 配置文件中添加SpringMVC监听器,和分发器配置
web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>TestWebSocket</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/test/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener></web-app>
- 配置Spring配置文件applicationContext.xml
这个文件有两种配置,分别对于注解的方式和XML配置的方式,两种方式的任务主要是配置Bean的初始化,还有websocket的配置初始化。
笔者的applicationContext.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: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/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> <context:component-scan base-package="test.websocket"/> <!-- <websocket:handlers> <websocket:mapping path="/myHandler" handler="myHandler"/> </websocket:handlers> <bean id="myHandler" class="MyHandler"/> --></beans>
component-scan 实现的注解的扫描,从而实现注解功能的实现,该功能是Spring AOP功能,需要AOP库。参考文档
如果没有采用注解实现,也可以手动在applicationContext.xml种配置websocket处理器,参见上面的配置文件。
SpringMVC + WebSocket + SockJs
客户端使用SockJs可以实现更好的浏览器兼容性, 示例参考官方网站,很简单,sockjs-client github链接
SockJs是如何实现服务端/客户端兼容的?通过尝试服务器的支持能力,从而确认是否支持特定的协议,这些协议包括:websocket ,xhr-streaming,xdr-streaming,eventsource…这些在特定的环境下会依次采用,也可以由客户端指定。比如websocket需要ws协议,如果经过没有相关配置的apache/ngnix,协议就会退化到轮询的websocket实现。通过协议退化,就保重了功能的实现。
比如Aapache需要配置如下才可以访问后端的Tomcat的websocket:
RewriteEngine On RewriteCond %{REQUEST_URI} ^/JFGJ/sockjs/webSocketServer/.*/websocket$ [NC] RewriteRule /(.*) ws://localhost:9090/$1 [P,L] ProxyPass /JFGJ/sockjs/webSocketServer http://localhost:9090/JFGJ/sockjs/webSocketServer ProxyPassReverse /JFGJ/sockjs/webSocketServer http://localhost:9090/JFGJ/sockjs/webSocketServer
笔者项目的sockjs的端点为:/JFGJ/sockjs/webSocketServer,/JFGJ/sockjs/webSocketServer/.*/websocket表达式标识对websocket的请求需要映射为ws协议(这个协议保护特殊的http头)。
如果遇到问题欢迎在留言区交流。
- SpringMVC WebSocket Apache代理 相关技术点总结
- websocket相关技术比较
- 自动化-Selenium WebDriver相关技术点总结
- springMVC+spring+MyBatis+websocket技术整合
- UITableView相关技术点
- 代理相关总结
- SpringMVC学习相关总结
- andriod 技术点总结
- ionic技术点总结
- 前端技术点总结
- Jquery相关技术点收集
- MySQL相关技术总结
- websocket相关
- spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)
- spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)
- spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)
- spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)
- spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)
- 代码之髓读后感——关于学习
- 链表(单向、双向、单向循环、双向循环)学习过程总结——有源代码、注释和示意图
- spring boot中spring.profiles.active的用法
- Mybatis整理
- springMVC 多图片多name上传
- SpringMVC WebSocket Apache代理 相关技术点总结
- 博客迁移通知
- Add Strings
- 5-1 抢红包 (25分)
- 大数据告诉你中国人喜欢用什么来刮胡子
- 【错误】The specified child already has a parent.
- 7.11--SSH学习之Struts拦截器
- R中字段抽取、字段合并、字段匹配
- CSS样式设置小技巧