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这里不多说,直接切 ...
随机推荐
- 解决运行Maven是报错:No goals have been specified for this build
pom.xml文件<build>标签后面加上<defaultGoal>compile</defaultGoal>即可
- IOS版微信小视频导出方法
1.在电脑上连接手机,打开iTools 选择 应用-应用-文件共享. 2.依次打开/Library/WechatPrivate/6e2809aac61608de6a6cc55d9570d25b/Sig ...
- win7官方下载地址
win7官方下载地址 http://microsoftstore.me/category/microsoft/windows/
- _x和__all__(有所理解即可)
# -*- coding: utf-8 -*- #python 27 #xiaodeng #_x和__all__(有所理解即可) #_x #不能使用from module import *导入 [注意 ...
- jQuery写缓存之:sessionStorage的运用,配合PHP将不同tab页的数据写入后台
JS(jQuery)写缓存之:sessionStorage的运用: 结果就是讲存储的DOM对象value传到后台PHP,进行foreach(){} 解析JSON成二维数组 示例页面:http://ww ...
- hduoj------确定比赛名次
拓扑排序结合代码的完整理解 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- Windows右键菜单设置与应用技巧
http://blog.163.com/lee_honleon/blog/static/555251522008014258896/ 需要修改注册表,挺麻烦的.最好还是把迅雷卸了重装,不会影响什么 ...
- RHCE7 -- systemctl命令
查询所有单元的状态: [root@rhce7 ~]# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automo ...
- Unix环境高级编程(十)信号续
1.signal函数 Unix系统的信号机制最简单的接口是signal函数,函数原型如下: #include <signal.h> typedef void (*sighandler_t) ...
- Linux时间子系统(十七) ARM generic timer驱动代码分析
一.前言 关注ARM平台上timer driver(clocksource chip driver和clockevent chip driver)的驱动工程师应该会注意到timer硬件的演化过程.在单 ...