场景

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();
}
}
  1. 实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
  2. registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
  3. setAllowedOrigins(String[] domains),允许指定的域名或IP(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。如果不限时使用"*"号,如果指定了域名,则必须要以http或https开头。
  4. addInterceptors,顾名思义就是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。
  5. 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详解的更多相关文章

  1. Spring配置文件详解 – applicationContext.xml文件路径

    Spring配置文件详解 – applicationContext.xml文件路径 Java编程                 spring的配置文件applicationContext.xml的默 ...

  2. spring配置文件详解--真的蛮详细

    spring配置文件详解--真的蛮详细   转自: http://book.51cto.com/art/201004/193743.htm 此处详细的为我们讲解了spring2.5的实现原理,感觉非常 ...

  3. 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理

    Spring AOP详解 . JDK动态代理.CGLib动态代理  原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...

  4. J2EE进阶(四)Spring配置文件详解

    J2EE进阶(四)Spring配置文件详解 前言 Spring配置文件是用于指导Spring工厂进行Bean生产.依赖关系注入(装配)及Bean实例分发的"图纸".Java EE程 ...

  5. Spring RestTemplate详解

    Spring RestTemplate详解   1.什么是REST? REST(RepresentationalState Transfer)是Roy Fielding 提出的一个描述互联系统架构风格 ...

  6. spring事务详解(五)总结提高

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.概念 ...

  7. spring事务详解(四)测试验证

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  8. spring事务详解(二)简单样例

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  9. spring事务详解(三)源码详解

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

随机推荐

  1. bootstrap的编辑标记 angularjs input 弹出框

    .html <div> {{instance.description}} <span class="glyphicon glyphicon-pencil btn-link& ...

  2. Consul 服务发现和配置

    Service discovery and configuration made easy. Distributed, highly available, and datacenter-aware. ...

  3. 【转】虚拟机VMware3种网络模式(桥接、nat、Host-only)的工作原理

     VMware网络配置详解一:三种网络模式简介 安装好虚拟机以后,在网络连接里面可以看到多了两块网卡: 其 中VMnet1是虚拟机Host-only模式的网络接口,VMnet8是NAT模式的网络接口, ...

  4. nice

    我们在使用$top的时候有一列NI参数,这个参数就是进程的nice值,用来表示进程在系统调度中的优先级,Linux中的进程nice从-20到+19,越小表明调度的优先级越高,用户进程的最小nice值就 ...

  5. shell执行mysql命令

    难点主要在参数的传递方式吧,不过查资料后发现很简单. 1.使用-e参数传递命令,适用于简单语句      mysql -uuser -ppasswd -e "create database ...

  6. delphi 相对路径

    ..代表上级目录 .代表当前目录 \代表目录分隔 ..\..\表上上一级目录

  7. Sqlserver2008 数据库镜像会话的初始连接

    sqlserver2008 数据库镜像服务配置完成后,大家会发现我们有了两个数据库服务,这两个服务可以实现自动故障转移,那么我们的程序如何实现自动连接正常的数据库呢? 这个问题很简单,使用ADO.NE ...

  8. HowTo: Linux Server Change OR Setup The Timezone

    Method 1 #tzselect # select timezone e.g. Asia/Shanghai#echo 'Asia/Shanghai' > /etc/timezone # se ...

  9. JAVA爬虫挖取CSDN博客文章

    开门见山,看看这个教程的主要任务,就去csdn博客,挖取技术文章,我以<第一行代码–安卓>的作者为例,将他在csdn发表的额博客信息都挖取出来.因为郭神是我在大学期间比较崇拜的对象之一.他 ...

  10. 2014 UESTC暑前集训图论专题解题报告

    A.方老师和缘分 http://www.cnblogs.com/whatbeg/p/3765621.html B.方老师和农场 http://www.cnblogs.com/whatbeg/p/376 ...