WebSocket实践

WebSocket

1 WebSocket概述

1)WebSocket是一种网络通信协议,是HTML5开始提供的一种在单个TCP连接上进行全双工通信的协议;是为了兼容现有浏览器的握手规范;

2)是一种浏览器与服务器进行全双工通信的网络技术,属于应用层协议,基于TCP传输协议,并复用HTTP的握手通道;

3)在 WebSocketAPI中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

4)浏览器通过 JavaScript向服务器发出建立 WebSocket连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP连接直接交换数据。

5)当获取 WebSocket连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

2 WebSocket与HTTP协议

1)HTTP协议只能由客户端发起通信,这种单向请求的特点,带来的问题是如果服务器有连续的状态变化,客户端获知非常麻烦,只能用轮询的方式,每隔一段时间,发出一个询问,了解服务器有没有新的信息,这种效率比较低,浪费资源;

2)websocket是一个持久化的协议;而HTTP是非持久化协议;

3)HTTP1.0生命周期是通过Request界定,一个Request一个Response,则请求就结束了;HTTP1.1中有一个keep-alive,在一个HTTP连接中,可以发送多个Request,接收多个Response,Response和Request对应的,且Response是被动的,不能主动发起;

4)http是一个无状态协议;

引用图1

3 WebSocket特点

3.1 优点

1)服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种;

2)支持双向通信,实时性更强;

3)更好的二进制支持;

4)较少的控制开销。连接创建后,ws客户端、服务端进行数据交换时,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10字节(取决于数据长度),客户端到服务端的话,需要加上额外的4字节的掩码。而HTTP协议每次通信都需要携带完整的头部。

5)支持扩展。ws协议定义了扩展,用户可以扩展协议,或者事项自定义的子协议。(比如支持自定义压缩算法等)

3.2 举例

客户端发起:

引用图2

服务端回复:服务端返回内容如下,状态代码101表示协议切换。到此完成协议升级,后续的数据交互都按照新的协议来

引用图3

• Connection: Upgrade:表示要升级协议

• Upgrade: websocket:表示要升级到websocket协议。

• Sec-WebSocket-Version: 13:表示websocket的版本。如果服务端不支持该版本,需要返回一个Sec-WebSocket-Versionheader,里面包含服务端支持的版本号。

• Sec-WebSocket-Key:与后面服务端响应首部的Sec-WebSocket-Accept是配套的,提供基本的防护,比如恶意的连接,或者无意的连接。

4 WebSocket原理

4.1 其他方式的被动性

1)ajax轮询:让浏览器每隔几秒就发送一次请求,询问服务器是否有信息;


引用叙述1

2)long poll:类似于ajax轮询,采取阻塞模型(一直打电话,没收到对方回应就不挂电话),客户端发起连接后,如果没信息,就一直不返回Response给客户端,直到有消息才返回,然后客户端再次建立连接;

引用叙述2

3)websocket:只需要经过一次HTTP请求,就可以不断的互通消息;


引用叙述3

4.2 websocket的产生

1)ajax轮询需要服务器有很快的处理速度和资源;long poll需要有很高的并发,及同时接待客户的能力;

2)websocket在服务器完成协议升级后(HTTP->websocket),服务端就可以主动推送消息给客户端;

3)只需要经过一次HTTP请求,就可以不断的互通消息;解决了服务器消耗资源以及同步延迟问题;

5 常用属性

5.1 @WebSocketEndpoint

注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。

5.2 @onOpen

打开一个新连接,即有新连接时,会调用被此注解的方法。

5.3 @onClose

关闭连接时调用。

5.4 @onMessage

当服务器接收到客户端发送的消息时所调用的方法。

5.5 @PathParam

接收 uri参数的,与@PathVariable功能差不多,可通过url获取对应值

6 WebSocket 后端JAVA实现

6.1 pom文件依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
依赖

6.2 运行类

1)添加注解:

@EnableWebSocket

2)添加Bean:

@Bean
 public ServerEndpointExporter serverEndpointExporter() {
 return new ServerEndpointExporter();
 }
@Bean

6.3 WebSocket controller类

1)注解:

@ServerEndpoint(value = "/heartbeatMonitor/{userId}")
@Component

2)其他类注入方式:


注入

3)方法使用:

@ServerEndpoint(value = "/websocket/{usernick}")为例

1.  @OnOpen
2.  public void onOpen(@PathParam(value = "usernick") String userNick,Session session) {
3.  String message = "有新游客[" + userNick + "]加入聊天室!";
4.  log.info(message);
5.  WebSocketUtil.addSession(userNick, session);    
6.  //此时可向所有的在线通知 某某某登录了聊天室 
7.  WebSocketUtil.sendMessageForAll(message);
8.  }

10.  @OnClose
11.  public void onClose(@PathParam(value = "usernick") String userNick,Session session) {
12.  String message = "游客[" + userNick + "]退出聊天室!";
13.  log.info(message);
14.  WebSocketUtil.remoteSession(userNick);  
15.  //此时可向所有的在线通知 某某某登录了聊天室 
16.  WebSocketUtil.sendMessageForAll(message);
17.  }
19.  @OnMessage
20.  public void OnMessage(@PathParam(value = "usernick") String userNick, String message) {
21.  //类似群发
22.  String info = "游客[" + userNick + "]:" + message;
23.  log.info(info);
24.  WebSocketUtil.sendMessageForAll(message);
25.  }
27.  @OnError
28.  public void onError(Session session, Throwable throwable) {
29.  log.error("异常:", throwable);
30.  try {
31.  session.close();
32.  } catch (IOException e) {
33.  e.printStackTrace();
34.  }
35.  throwable.printStackTrace();
36.  }
websocket方法

6.4 测试

http://coolaf.com/tool/chattest

1)连接


websocket open

2)发送消息


websocket onMessage
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容