Spring4.0系列9-websocket简单应用
Spring4.0系列4-Meta Annotation(元注解)
Spring4.0系列6-Generic Qualifier(泛型限定)
Spring4.0系列7-Ordering Autowired Collections
Spring 4.0的一个最大更新是增加了websocket的支持。websocket提供了一个在web应用中的高效、双向的通讯,需要考虑到客户端(浏览器)和服务器之间的高频和低延时消息交换。一般的应用场景有:在线交易、游戏、协作、数据可视化等。
使用websocket需要考虑的浏览器的支持(IE<10不支持),目前主流的浏览器都能很好的支持websocket。
websocket协议中有一些子协议,可以从更高的层次实现编程模型,就像我们使用HTTP而不是TCP一样。这些子协议有STOMP,WAMP等。
本教程只考虑websocket的简单实用,包含Spring对JSR-356的支持及Spring WebSocket API。
1、Java API for WebSocket(JSR-356)
Java API for WebSocket已经是Java EE 7的一部分。它定义了两类endpoit(都是EndPoint类的子类),使用注解标识@ClientEndpoint和@ServerEndpoint。
1.1 Servlet容器扫描初始化
通过Spring初始化一个endpoint,只需配置一个SpringConfigurator在类上的@ServerEndpoint注解上。
- import javax.websocket.server.ServerEndpoint;
- import org.springframework.web.socket.server.endpoint.SpringConfigurator;
- @ServerEndpoint(value = "/echo", configurator = SpringConfigurator.class);
- public class EchoEndpoint {
- private final EchoService echoService;
- @Autowired
- public EchoEndpoint(EchoService echoService) {
- this.echoService = echoService;
- }
- @OnMessage
- public void handleMessage(Session session, String message) {
- // ...
- }
- }
上例假设SpringContextLoaderListener用来加载配置,这是个典型的web应用。Servlet容器将通过扫描@ServerEndpoint和SpringConfigurator初始化一个新的websocket会话。
1.2 Spring 初始化
如果你想使用一个单独的实例而不使用Servlet容器扫描,将EchoEndpoint类声明称一个bean,并增加一个ServerEndpointExporter的bean:
- import org.springframework.web.socket.server.endpoint.ServerEndpointExporter;
- @Configuration
- public class EndpointConfig {
- @Bean
- public EchoEndpoint echoEndpoint() {
- return new EchoEndpoint(echoService());
- }
- @Bean
- public EchoService echoService() {
- // ...
- }
- @Bean
- public ServerEndpointExporter endpointExporter() {
- return new ServerEndpointExporter();
- }
- }
EchoEndpoint 可以通过EndPointRegistration发布:
- import org.springframework.web.socket.server.endpoint.ServerEndpointExporter;
- import org.springframework.web.socket.server.endpoint.ServerEndpointRegistration;
- @Configuration
- public class EndpointConfig {
- @Bean
- public EndpointRegistration echoEndpoint() {
- return new EndpointRegistration("/echo", EchoEndpoint.class);
- }
- @Bean
- public ServerEndpointExporter endpointExporter() {
- return new ServerEndpointExporter();
- }
- // ..
- }
本例源码:spring-websocket-test-endpoint.zip
2、Spring WebSocket API
Spring WebSocket API提供了SockJS的支持,且有些容器如Jetty 9目前还没有对JSR-356的支持,所以有Spring WebSocket API是必要的。
Spring WebSocket API的核心接口是WebSocketHandler。下面是一个处理文本消息的handler的实现:
- import org.springframework.web.socket.adapter.TextWebSocketHandlerAdapter;
- public class EchoHandler extends TextWebSocketHandlerAdapter {
- @Override
- public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
- session.sendMessage(message);
- }
- }
WebSocketHandler可以通过WebSocketHttpRequestHandler插入到Spring MVC里:
- import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;
- @Configuration
- public class WebConfig {
- @Bean
- public SimpleUrlHandlerMapping handlerMapping() {
- Map<String, Object> urlMap = new HashMap<String, Object>();
- urlMap.put("/echo", new WebSocketHttpRequestHandler(new EchoHandler()));
- SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
- hm.setUrlMap(urlMap);
- return hm;
- }
- }
SockJS服务器端的支持
SockJs是一个脚本框架,它提供类似于websocket的编程模式但是可以适应不同的浏览器(包括不支持websocket的浏览器)。
开启SockJS的支持,声明一个SockJsService,和一个url映射,然后提供一个WebSocketHandler来处理消息。虽然 我们是哟个SockJS我们开发的方式是一样的,但是随着浏览器的不同传输的协议可以是Http Streaming,long polling等。
- import org.springframework.web.socket.sockjs.SockJsService;
- // ...
- @Configuration
- public class WebConfig {
- @Bean
- public SimpleUrlHandlerMapping handlerMapping() {
- SockJsService sockJsService = new DefaultSockJsService(taskScheduler());
- Map<String, Object> urlMap = new HashMap<String, Object>();
- urlMap.put("/echo/**", new SockJsHttpRequestHandler(sockJsService, new EchoHandler()));
- SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
- hm.setUrlMap(urlMap);
- return hm;
- }
- @Bean
- public ThreadPoolTaskScheduler taskScheduler() {
- ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
- taskScheduler.setThreadNamePrefix("SockJS-");
- return taskScheduler;
- }
- }
在我们实际使用中我们会使用WebSocketConfigurer集中注册WebSocket服务:
- @Configuration
- @EnableWebMvc
- @EnableWebSocket//开启websocket
- public class WebConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
- @Override
- public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
- registry.addHandler(echoWebSocketHandler(), "/echo"); //提供符合W3C标准的Websocket数据
- registry.addHandler(snakeWebSocketHandler(), "/snake");
- registry.addHandler(echoWebSocketHandler(), "/sockjs/echo").withSockJS();//提供符合SockJS的数据
- registry.addHandler(snakeWebSocketHandler(), "/sockjs/snake").withSockJS();
- }
- @Bean
- public WebSocketHandler echoWebSocketHandler() {
- return new EchoWebSocketHandler(echoService());
- }
- @Bean
- public WebSocketHandler snakeWebSocketHandler() {
- return new PerConnectionWebSocketHandler(SnakeWebSocketHandler.class);
- }
- @Bean
- public DefaultEchoService echoService() {
- return new DefaultEchoService("Did you say \"%s\"?");
- }
- // Allow serving HTML files through the default Servlet
- @Override
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
- configurer.enable();
- }
- }
SockJS客户端代码:
- ws = new SockJS(url, undefined, {protocols_whitelist: transports}) ; //初始化 websocket
- 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);
- };
- ws.send(message);//向服务端发送消息
程序用maven打成war后用tomcat 8发布查看效果。
本例源码:spring-websocket-test-master.zip
新书推荐《JavaEE开发的颠覆者: Spring Boot实战》,涵盖Spring 4.x、Spring MVC 4.x、Spring Boot企业开发实战。
京东地址:http://item.jd.com/11894632.html
当当地址:http://product.dangdang.com/23926195.html
亚马逊地址:http://www.amazon.cn/图书/dp/B01D5ZBFUK/ref=zg_bsnr_663834051_6
淘宝地址:https://item.taobao.com/item.htm?id=528426235744&ns=1&abbucket=8#detail
或自己在京东、淘宝、亚马逊、当当、互动出版社搜索自选。
Spring4.0系列9-websocket简单应用的更多相关文章
- [CXF REST标准实战系列] 二、Spring4.0 整合 CXF3.0,实现测试接口(转)
转自:[CXF REST标准实战系列] 二.Spring4.0 整合 CXF3.0,实现测试接口 文章Points: 1.介绍RESTful架构风格 2.Spring配置CXF 3.三层初设计,实现W ...
- [CXF REST标准实战系列] 二、Spring4.0 整合 CXF3.0,实现测试接口
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章Points: 1.介绍RESTful架构 ...
- HTTP协议系列(3)---包括WebSocket简单介绍
一.HTTPS HTTP是超文本传输协议,那HTTPS是什么尼?要明白HTTPS是什么先要明白HTTP的缺点,想一下我们在使用HTTP的时候会有那些缺点尼? 1.通信使用的明文(不加密),内容 ...
- Spring 4.0 中的 WebSocket 架构
两年前,客户端与服务器端的全双工双向通信作为一个很重要的功能被纳入到WebSocket RFC 6455协议中.在HTML5中,WebSocket已经成为一个流行词,大家对这个功能赋予很多构想,很多时 ...
- [渣译文] SignalR 2.0 系列: SignalR简介
原文:[渣译文] SignalR 2.0 系列: SignalR简介 英文渣水平,大伙凑合着看吧,并不是逐字翻译的…… 这是微软官方SignalR 2.0教程Getting Started with ...
- SignalR 2.0 系列: SignalR简介
SignalR 2.0 系列: SignalR简介 英文渣水平,大伙凑合着看吧,并不是逐字翻译的…… 这是微软官方SignalR 2.0教程Getting Started with ASP.NET S ...
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- [转]Struts2.3.16.1+Hibernate4.3.4+Spring4.0.2 框架整合
原文地址:http://blog.csdn.net/ycb1689/article/details/22928519 最新版Struts2+Hibernate+Spring整合 目前为止三大框架最新版 ...
- Spring4.0编程式定时任务配置
看过很多定时调度的配置,大多使用XML配置,觉得比较麻烦,也比较老套.这里介绍一种基于spring4.0注解编程式配置定时任务,简单清晰,使用方便.. 至于引入spring相关jar这里不多说,直接切 ...
随机推荐
- Cocos2d-x新建模板编译问题总汇
0:关于使用VC模板创建模板时候脚本错误.改动..\cocos2d-x-2.2.2\template\msvc\CCAppWiz.win32\HTML\1033中文件属性中:安全->解除锁定. ...
- NGINX原理 之 SLAB分配机制(转)
1 引言 众所周知,操作系统使用伙伴系统管理内存,不仅会造成大量的内存碎片,同时处理效率也较低下.SLAB是一种内存管理机制,其拥有较高的处理效率,同时也有效的避免内存碎片的产生,其核心思想是预分配. ...
- maven 创建web项目的标准目录结构
maven 创建web项目的标准目录结构 CreateTime--2018年4月18日21:05:37 Author:Marydon 1.标准目录介绍(开发目录) 2.在eclipse下,目录展示 ...
- 【shell】正则表达式
当一个文件或命令输出中抽取或过滤文本时,可以使用正则表达式(RE),正则表达式是一些特殊或很不特殊的字符串模式的集合. 在Linux中grep.awk.sed均可解释正则 1.基本元字符集及其定义 ^ ...
- org.apache.commons.lang.StringUtils中isEmpty和isBlank的区别
public static boolean isEmpty(String str) 判断某字符串是否为空,为空的标准是str==null或str.length()==0 StringUtils.isE ...
- Jquery.getJSON的缓存问题的处理方法
$.getJSON()存在缓存问题,如果其调用的url之前曾经调用过的话,回调函数就会直接在缓存里取得想要得值,而不是进入到后台 在项目中遇到一个问题,在火狐下,$.getJSON();请求数据一 ...
- Python 实现的、带GUI界面的词云生成器
代码地址如下:http://www.demodashi.com/demo/14233.html 详细说明: "词云"就是数据可视化的一种形式,给出一段文本,根据文本中词语的出现频率 ...
- openGL 坐标系的互相转换
openGL坐标系包括旋转,平移,缩放被塞在一个矩阵里面. 坐标系之间的转换基础是矩阵的运算. 每个矩阵代表的坐标系,就是是原点坐标系通过旋转.平移,缩放得到的坐标系. 当一个矩阵右乘一个向量或是还有 ...
- mysql中char,varchar,text
1.char char最大长度是255字符,注意是字符数和字符集没关系. 1)可以有默认值, 2)尾部有空格会被截断 3)不管汉字.英文,还是其他编码,都可以存255字符 2.varchar 1)va ...
- ios block常见的错误(一)
Block是OC中的一种数据类型,在iOS开发中被广泛使用. 在实际的使用和面试过程中,经常发现同事或面试者对block了解得不够透彻,本博文将列举常见block错误来对其加深理解. 示例代码1: ; ...