spring WebSocket详解
场景
websocket是Html5新增加特性之一,目的是浏览器与服务端建立全双工的通信方式,解决http请求-响应带来过多的资源消耗,同时对特殊场景应用提供了全新的实现方式,比如聊天、股票交易、游戏等对对实时性要求较高的行业领域。
背景
在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。目前各大主流浏览器都支持websocket,IE浏览器要IE10+
一、POM依赖
POM依赖,spring4.1.4.RELEASE,spring核心依赖请自行添加,下面是websocket相关jar
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
二、WebSocket入口
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//允许连接的域,只能以http或https开头
String[] allowsOrigins = {"http://www.xxx.com"};
//WebIM WebSocket通道
registry.addHandler(chatWebSocketHandler(),"/ webSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor());
registry.addHandler(chatWebSocketHandler(), "/sockjs/w ebSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor()).withSockJS();
}
@Bean
public ChatWebSocketHandler chatWebSocketHandler() {
return new ChatWebSocketHandler();
}
@Bean
public WebSocketHandshakeInterceptor myInterceptor(){
return new WebSocketHandshakeInterceptor();
}
}
- 实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
- registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
- setAllowedOrigins(String[] domains),允许指定的域名或IP(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。如果不限时使用"*"号,如果指定了域名,则必须要以http或https开头。
- addInterceptors,顾名思义就是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。
- spring websocket也支持STOMP协议,下回再分享。
三、拦截器实现
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object
> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
attributes.put("username",userName);
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}
beforeHandshake,在调用handler前处理方法。常用在注册用户信息,绑定WebSocketSession,在handler里根据用户信息获取WebSocketSession发送消息。
四、Handler处理类
public class ChatWebSocketHandler extends TextWebSocketHandler{
private final static List<WebSocketSession> sessions = Collections.synchronizedList(new ArrayList<WebSocketSession>());
//接收文本消息,并发送出去
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
chatTextMessageHandler(message.getPayload());
super.handleTextMessage(session, message);
}
//连接建立后处理
@SuppressWarnings("unchecked")
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.debug("connect to the websocket chat success......");
sessions.add(session);
//处理离线消息
}
//抛出异常时处理
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if(session.isOpen()){
session.close();
}
logger.debug("websocket chat connection closed......");
sessions.remove(session);
}
//连接关闭后处理
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
logger.debug("websocket chat connection closed......");
sessions.remove(session);
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
五、客户端连接
var host = window.location.host;
var websocket;
if ('WebSocket' in window) {
websocket = new ReconnectingWebSocket("ws://"
+ host + "/webSocketIMServer", null, {debug:true, maxReconnectAttempts:4});
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://" + host
+ "/webSocketIMServer");
} else {
websocket = new SockJS("http://" + host
+ "/sockjs/webSocketIMServer");
}
websocket.onopen = function(evnt) {
console.log("websocket连接上");
};
websocket.onmessage = function(evnt) {
messageHandler(evnt.data);
};
websocket.onerror = function(evnt) {
console.log("websocket错误");
};
websocket.onclose = function(evnt) {
console.log("websocket关闭");
}
这里用到了ReconnectingWebSocket.js,对浏览器自带websocket添加了扩展,例如重连,连接超时时间,失败重连间隔,尝试连接最大次数等。
项目主页:ReconnectingWebSocket
ps:如果有疑问,你也可以关注我的微信公众号『ITNotes』, 一起交流学习 。

spring WebSocket详解的更多相关文章
- Spring配置文件详解 – applicationContext.xml文件路径
Spring配置文件详解 – applicationContext.xml文件路径 Java编程 spring的配置文件applicationContext.xml的默 ...
- spring配置文件详解--真的蛮详细
spring配置文件详解--真的蛮详细 转自: http://book.51cto.com/art/201004/193743.htm 此处详细的为我们讲解了spring2.5的实现原理,感觉非常 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- J2EE进阶(四)Spring配置文件详解
J2EE进阶(四)Spring配置文件详解 前言 Spring配置文件是用于指导Spring工厂进行Bean生产.依赖关系注入(装配)及Bean实例分发的"图纸".Java EE程 ...
- Spring RestTemplate详解
Spring RestTemplate详解 1.什么是REST? REST(RepresentationalState Transfer)是Roy Fielding 提出的一个描述互联系统架构风格 ...
- spring事务详解(五)总结提高
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.概念 ...
- spring事务详解(四)测试验证
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- spring事务详解(二)简单样例
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
- spring事务详解(三)源码详解
系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...
随机推荐
- .Net魔法堂:提取注释生成API文档
一.前言 在多人协作的项目中,除了良好的代码规范外,完整的API文档也相当重要.通过文档我们快速了解系统各模块的实际接口,及其使用场景.使用示例,一定程度上降低沟通成本,和减少后期维护中知识遗失等风险 ...
- 清理DBA_DATAPUMP_JOBS中的孤立数据泵作业
今天在重构数据库时(将表空间中的表.索引转移到其它表空间)时,发现有两个奇怪的对象SYS_EXPORT_FULL_01.SYS_EXPORT_FULL_02搜索了一下,发现这个可能是EXPDP导出异常 ...
- SQL Server(七)——存储过程
一.概述 存储过程是一组编译在单个执行计划中的T-SQL语句 存储过程:就像函数一样的会保存在数据库中(可编程性) 存储过程的优点: 1.允许模块化程序设计 2.允许更快执行如果某操作需要大量T-SQ ...
- 十五天精通WCF——第九天 高级玩法之自定义Behavior
终于我又看完了二期爱情保卫战,太酸爽了,推荐链接:http://www.iqiyi.com/a_19rrgublqh.html?vfm=2008_aldbd,不多说,谁看谁入迷,下面言归正传, 看看这 ...
- SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)
前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...
- windows下socket学习(一)
关于socket的文章,园子里面有很多,其实无非就是 WSAStartup.socket.bind.listen.accept.recv.send(服务端),WSAStartup.socket.con ...
- Linux的文件时间
在windows下,一个文件有:创建时间.修改时间.访问时间.而在Linux下,一个文件也有三种时间,分别是:访问时间.修改时间.状态改动时间. 1.访问时间,读一次这个文件的内容,这个时间就会更新. ...
- PCIe 32GT/s 含义
如下: Jul 26 03:42:53 kernel: ixgbe 0000:01:00.1: PCI Express bandwidth of 32GT/s available Jul 26 03: ...
- PADS_AD_Cadence转换
PADS_AD_Cadence转换 软件版本:PADS的版本是PADS9.5,Altium designer的版本是Altium designer winter 09 PADS和AD的转换 PADS的 ...
- linux线程同步(4)-自旋锁
自旋锁与互斥量功能一样,唯一一点不同的就是互斥量阻塞后休眠让出cpu,而自旋锁阻塞后不会让出cpu,会一直忙等待,直到得到锁!!! 自旋锁在用户态使用的比较少,在内核使用的比较多!自旋锁的使用场景:锁 ...