1.导入maven依赖

        <!-- websocket -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>

2.创建类 HandshakeInterceptor 继承 HttpSessionHandshakeInterceptor

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception { /**
* 在拦截器内强行修改websocket协议,将部分浏览器不支持的 x-webkit-deflate-frame 扩展修改成
* permessage-deflate
*/
if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
}
String jspCode = ((ServletServerHttpRequest) request).getServletRequest().getParameter("jspCode");
if (jspCode != null) {
attributes.put("jspCode", jspCode);
} else {
return false;
}
return true;
} @Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
}

3.创建类 MyWebSocketConfig 继承 WebMvcConfigurerAdapter 并实现 WebSocketConfigurer

@Component
@EnableWebMvc
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
@Resource
MyWebSocketHandler handler; @Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addHandler(handler, "/websocket").addInterceptors(new HandshakeInterceptor());
registry.addHandler(handler, "/websocket/sockjs").addInterceptors(new HandshakeInterceptor()).withSockJS();
}
}

4.创建类 MyWebSocketHandler 实现 WebSocketHandler

@Component
public class MyWebSocketHandler implements WebSocketHandler { public static final Map<String, WebSocketSession> userSocketSessionMap; static {
userSocketSessionMap = new HashMap<String, WebSocketSession>();
} @Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
// TODO Auto-generated method stub
String jspCode = session.getId() + "-" + (String) session.getHandshakeAttributes().get("jspCode"); if (userSocketSessionMap.get(jspCode) == null) {
System.out.println("添加会话:" + jspCode);
userSocketSessionMap.put(jspCode, session);
}
} @Override
public void handleMessage(WebSocketSession session,
WebSocketMessage<?> message) throws Exception {
// TODO Auto-generated method stub
session.sendMessage(message);
} @Override
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
// TODO Auto-generated method stub
if (session.isOpen()) {
session.close();
}
Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<String, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID:" + entry.getKey());
break;
}
}
} @Override
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
// TODO Auto-generated method stub
System.out.println("Websocket:" + session.getId() + "已经关闭");
Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<String, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID:" + entry.getKey());
break;
}
}
} @Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
}

5.前段使用

<!-- websocket -->
<script type="text/javascript">
$(function() { var jspCode = "${user.userId}"; var websocket;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/ebcrawler/websocket?jspCode=" + jspCode);
} else if ('MozWebSocket' in window) {
websocket = new MozWebSocket("ws://localhost:8080/ebcrawler/websocket?jspCode=" + jspCode);
} else {
websocket = new SockJS("http://localhost:8080/ebcrawler/websocket/sockjs?jspCode=" + jspCode);
} websocket.onopen = function(event) {
$(".commonMsg").each(function() {
$(this).html($(this).html() + "已连接<br/>")
});
};
websocket.onmessage = function(event) {
var data = event.data;
var type = data.substring(0, data.indexOf("-"));
var msg = data.substring(data.indexOf("-") + 1);
if (type == "1") {
$("#doneMsg").html($("#doneMsg").html() + msg + "<br/>");
} else if (type == "2") {
$("#doingMsg").html(msg + "<br/>");
} else if (type == "3") {
$("#errorMsg").html(msg + "<br/>" + $("#errorMsg").html());
} else { } };
websocket.onerror = function(event) {
$(".commonMsg").each(function() {
$(this).html($(this).html() + "websocket发生错误<br/>")
});
};
websocket.onclose = function(event) {
$(".commonMsg").each(function() {
$(this).html($(this).html() + "已关闭<br/>")
});
};
});
</script>

6.后端使用

        //websocket发给前端
Iterator<Entry<String, WebSocketSession>> it = MyWebSocketHandler.userSocketSessionMap.entrySet().iterator();
// 发给同一userId的客户端
while (it.hasNext()) { final Entry<String, WebSocketSession> entry = it.next();
String keyUserId = entry.getKey().substring(entry.getKey().indexOf("-") + 1);
WebSocketSession session = entry.getValue();
if (session.isOpen() && keyUserId.equals(userId)) {
try {
if (session.isOpen()) {
synchronized(session) {
entry.getValue().sendMessage(new TextMessage(msg));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

  注意:当多线程发送消息时,同一个WebSocketSession一次只能发送条消息,所以需要用synchronize将session锁住

HTML5通讯协议——WebSocket的更多相关文章

  1. websocket通讯协议(10版本)简介

    前言: 工作中用到了websocket 协议10版本的,英文的协议请看这里: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotoc ...

  2. WebSocke实时通讯协议

    WebSocket 是什么? WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议 ...

  3. 带你认识HTML5中的WebSocket

    这篇文章主要介绍了带你认识HTML5中的WebSocket,本文讲解了HTML5 中的 WebSocket API 是个什么东东.HTML5 中的 WebSocket API 的用法.带Socket. ...

  4. HTML5新特性 websocket(重点)--多对多聊天室

    一.html5新特性  websocket(重点)--多对多聊天室 HTTP:超文本传输协议 HTTP作用:传输网页中资源(html;css;js;image;video;..) HTTP是浏览器搬运 ...

  5. 基于dubbo框架下的RPC通讯协议性能测试

    一.前言 Dubbo RPC服务框架支持丰富的传输协议.序列化方式等通讯相关的配置和扩展.dubbo执行一次RPC请求的过程大致如下:消费者(Consumer)向注册中心(Registry)执行RPC ...

  6. MODBUS-RTU通讯协议简介

    MODBUS-RTU通讯协议简介   什么是MODBUS? MODBUS 是MODICON公司最先倡导的一种软的通讯规约,经过大多数公司 的实际应用,逐渐被认可,成为一种标准的通讯规约,只要按照这种规 ...

  7. 【读书笔记】iOS-防止通讯协议被轻易破解的方法

    开发者可以选择类似Protobuf之类的二进制通讯协议或者自己实现通讯协议,对于传输的内容进行一定程度的加密,以增加黑客破解协议的难度. 参考资料: <iOS开发进阶> --唐巧

  8. CNN 美国有线电视新闻网 wapCNN WAP 指无线应用通讯协议 ---- 美国有线电视新闻网 的无线应用

    wapCNN  wap指无线应用通讯协议  CNN美国有线电视新闻网   固, wapCNN 美国有线电视新闻网的无线应用 -------------------------------------- ...

  9. Netty 对通讯协议结构设计的启发和总结

    Netty 通讯协议结构设计的总结 key words: 通信,协议,结构设计,netty,解码器,LengthFieldBasedFrameDecoder 原创 包含与机器/设备的通讯协议结构的设计 ...

随机推荐

  1. CSS 分栏结构

    CSS 固定左侧导航栏 left----左侧菜单 cont -- 实际内容 right  ---右侧附加内容   两栏布局---左侧高度为内容撑开的高度     方法一:[坏处是需要 float]   ...

  2. 【C++笔记】析构函数(destructor)

    “析构函数”是构造函数的反向函数. 在销毁(释放)对象时将调用它们. 通过在类名前面放置一个波形符 (~) 将函数指定为类的析构函数.   声明析构函数   析构函数是具有与类相同的名称但前面是波形符 ...

  3. Learn Node.js

    Learn Node.js Node: 脱离浏览器运行的JS,运行在服务端 基于Chrome浏览器的V8引擎,使用V8虚拟机解析和执行JS代码 创建简单的服务器: 创建一个server.js的文件 $ ...

  4. Java8 Lambda表达式原理扫盲

    背景 在使用Lamdba表达式,一直以为是内部类的方式实现的,但是一想如果每次调用都实例化一个内部类,性能肯定不好,难道Java里的lambda表达式真的是这么实现的吗?也许是该研究下原理了. 正文 ...

  5. python3.4 + pycharm 环境安装 + pycharm使用

    因个人是windows的环境,所以本文只讲windows环境下的python安装. 作为初用python的盆友,强烈建议只在电脑上装一个python版本就好了,不然就进了各种坑里了. 第一步:下载和安 ...

  6. 【干货】使用SIFT取证工作站校验文件哈希----哈希一致则文件具备完整性

    此实验来源于课程活动部分:第1单元:计算机取证基础  1.3活动和讨论  活动:* nix系统中文件的基本散列 注意:本博客更多的信息可能没有交代完善,有的人看不明白是因为,我知道,但是没有写出来.本 ...

  7. 【译】索引进阶(七):SQL SERVER中的过滤索引

    原文链接:传送门. To be continued...

  8. php跨域问题记录

    记录跨域问题 一.问题 在控制层加了如下代码: header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN'] ); header('Ac ...

  9. 【转】Python函数默认参数陷阱

    [转]Python函数默认参数陷阱 阅读目录 可变对象与不可变对象 函数默认参数陷阱 默认参数原理 避免 修饰器方法 扩展 参考 请看如下一段程序: def extend_list(v, li=[]) ...

  10. Uncaught DOMException: Failed to construct 'WebSocket': The URL

    生成socket对象地址有误