1.背景

1.1.WebSocket与普通Socket的差异

Socket

简单理解:Socket = IP地址 + 端口 + 协议。

具体来说,Socket是一套标准,它完成了对TCP/IP的高度封装,屏蔽网络细节以方便开发者更好地进行网络编程。Socket有自己的原语。

WebSocket

WebSocket是一个持久化的协议,它是伴随HTTP5而出的协议,用来解决http不支持持久化连接的问题。

总之,WebSocket和Socket其实是两个东西,Socket一个是网编编程的标准接口,而WebSocket是应用层通信协议。

但是,说WebSocket与Socket的差异更多说的是:WebSocket与HTTP无状态被动协议的差异,或者说是WebSocket与Ajax轮询和long poll等实现实时信息传输方式的差异,这也是本文需要讨论的问题。

1.2.http的非持久性

http的生命周期通过Request来界定,在HTTP1.0中一个Request一个Response,这次HTTP请求就结束了。

HTTP1.1进行了改进,通过使用一个keep-alive,在一个HTTP连接中,可以发送多个Request,接收多个Response,但其实本质上还是一个Request只能有一个Response,并且Reponse是被动的,不能主动发起。

2.WebSocket原理

2.1.WebSocket握手

首先,虽然WebSocket是随着http5出的协议,但是WebSocket和http协议没什么关系,两者关系如下所示:

两者有交集,但不存在包含关系。

WebSocket借用了HTTP协议来完成一部分握手。

首先,我们来看个典型的Websocket握手

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

熟悉HTTP的童鞋可能发现了,这段类似HTTP协议的握手请求中,多了几个东西。

我会顺便讲解下作用。

新增1:

Upgrade: websocket
Connection: Upgrade

这个就是Websocket的核心了,告诉Apache、Nginx等服务器,这是Websocket协议,而不是http,快点帮我找到对应的助理处理一下。

新增2:

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

  • Sec-WebSocket-Key 是一个Base64 encode的值,这个是浏览器随机生成的,用来验证服务器是不是真的是Websocket助理。
  • Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~
  • Sec-WebSocket-Version 是告诉服务器所使用的Websocket Draft(协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,当初Websocket协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用的一个东西~ 服务员,我要的是13岁的噢→_→

然后服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦!

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

这里开始就是HTTP最后负责的区域了,告诉客户,我已经成功切换协议啦~

Upgrade: websocket
Connection: Upgrade

首先Upgrade何Connection字段依然是固定的,告诉客户端即将升级的是Websocket协议,而不是mozillasocketlurnarsocket或者shitsocket。

然后,Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key。服务器:好啦好啦,知道啦,给你看我的ID CARD来证明行了吧。。

后面的,Sec-WebSocket-Protocol 则是表示最终使用的协议。

至此,HTTP已经完成它所有工作了,接下来就是完全按照Websocket协议进行了。

2.2.ajax轮询与long poll的被动性

在讲Websocket之前,我就顺带着讲下 long poll 和 ajax轮询 的原理。虽然这两种方式也可以实现实时信息传递,但他们都存在一个共同的问题,基于http协议。

ajax轮询

ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

场景再现:

客户端:啦啦啦,有没有新信息(Request)

服务端:没有(Response)

客户端:啦啦啦,有没有新信息(Request)

服务端:没有。。(Response)

客户端:啦啦啦,有没有新信息(Request)

服务端:你好烦啊,没有啊。。(Response)

客户端:啦啦啦,有没有新消息(Request)

服务端:好啦好啦,有啦给你。(Response)

客户端:啦啦啦,有没有新消息(Request)

服务端:。。。。。没。。。。没。。。没有(Response)

long poll

long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

场景再现

客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)

服务端:额。。 等待到有消息的时候。。来 给你(Response)

客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -

loop

从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性

何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。

简单地说就是,服务器是一个很懒的冰箱,不会、不能主动发起连接,但是上司有命令,如果有客户来,不管多么累都要好好接待。

说完这个,我们再来说一说上面的缺陷

从上面很容易看出来,不管怎么样,上面这两种都是非常消耗资源的。

ajax轮询 需要服务器有很快的处理速度和资源。(速度)

long poll 需要有很高的并发,也就是说同时接待客户的能力。(场地大小)

所以ajax轮询 和long poll 都有可能发生这种情况。

客户端:啦啦啦啦,有新信息么?

服务端:月线正忙,请稍后再试(503 Server Unavailable)

客户端:。。。。好吧,啦啦啦,有新信息么?

服务端:月线正忙,请稍后再试(503 Server Unavailable)

客户端:

然后服务端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。

2.3.WebSocket协议

通过上面这个例子,我们可以看出,这两种方式都不是最好的方式,需要很多资源。

HTTP还是一个无状态协议。Websocket出现了。他解决了HTTP的这几个难题。简单来说就是WebSocket只需一次HTTP请求、服务端主动推送消息。

当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。

所以上面的情景可以做如下修改。

客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)

服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)

客户端:麻烦你有信息的时候推送给我噢。。

服务端:ok,有的时候会告诉你的。

服务端:balabalabalabala

服务端:balabalabalabala

服务端:哈哈哈哈哈啊哈哈哈哈

服务端:笑死我了哈哈哈哈哈哈哈

就变成了这样,只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。

在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你。

这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。

那么为什么他会解决服务器上消耗资源的问题呢?

答案还是从WebSocket机制来回答:一次请求,持久连接,无需反复鉴别用户,服务端主动PUSH

首先,我们得了解WebSocket请求过程,我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。

简单地说,我们有一个非常快速的接线员(Nginx),他负责把问题转交给相应的客服(Handler)

本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢。,导致客服不够。

Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员再统一转交给客户。

这样就可以解决客服处理速度过慢的问题了。

其次,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是无状态性的,每次都要重新传输identity info(鉴别信息),来告诉服务端你是谁。

虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。

但是Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的无状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity info的信息。

同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了。

总结

HTTP协议是被动的无状态协议,一个Request对应一个Response,每次Request,客户端都需要重复带上用于鉴别客户端身份的信息到服务端,且服务端无法主动推送消息给客户端。针对HTTP这种效率低、响应不及时、浪费通信带宽和服务端资源的情况,WebSocket应运而生,WebSocket采用一次请求,持久连接方式解决了反复校验客户端身份问题,服务端建立连接后可以主动推送消息给客户端,因此通信效率大大增加,同时也节约了客户端、服务端和网络资源。

以上。

websocket如何区分用户_WebSocket与普通Socket的差异相关推荐

  1. websocket如何区分用户_WebSocket区分不同客户端两种方法(HttpSession和@PathParam)

    介绍 在使用websocket来制作多人即时聊天工具的时候,难免会遇到一个问题,如何区分不同的客户端.想要解决这个问题就等于是要解决这样一个问题:如何把当前登录用户的userId传给服务端呢?因为不同 ...

  2. websocket如何区分用户_Node.js Websocket如何区分不同的用户

    本篇教程介绍了Node.js Websocket如何区分不同的用户,希望阅读本篇文章以后大家有所收获,帮助大家对Node.js的理解更加深入. < 通过param1,param2来管理不同的ws ...

  3. websocket如何区分用户_实现:websocket判断用户是否在线

    根据我们之前的介绍,websocket是HTML5中新增的一个协议, 该协议可以实现服务器与客户端之间全双工通信. websocket在实时通信领域运用的比较多,比如社交聊天.弹幕.多玩家游戏.协同编 ...

  4. 【博客大赛】100行js代码实现网站在线用户数量统计 nodejs + socket.io方案

    需求提出 公司的在线培训平台,需要增加一个新功能:实时统计当前在线的用户数量并在终端界面上显示,需要的时候可以查询当前在线的用户的明细. 有3种技术方案可以选用: 1)改动后台代码,在用户登录和退出时 ...

  5. Springboot整合Websocket遇到的坑_websocket session不支持序列化,无法存储至redis_Websocket相关问题总结(Session共享,用户多端登录等)

    Springboot整合Websocket遇到的坑 一.使用Springboot内嵌的tomcat启动websocket 1.添加ServerEndpointExporter配置bean @Confi ...

  6. websocket中发生数据丢失_Websocket传输可靠性(重新连接时Socket.io数据丢失)

    其他人在其他答案和评论中暗示了这一点,但根本问题是Socket.IO只是一种传递机制,你不能单独依靠它来实现可靠的交付 . 唯一确定消息已成功传递给客户端的人 is the client itself ...

  7. linux区分用户的权限级别可用,如何限制Linux内核级别的特权用户访问?

    我在 learning Linux Kernel Programming找到了这个答案,我的问题更具体针对Linux内核的安全功能.我想知道如何限制特权用户或进程对其他进程和文件的访问权限,而不是ro ...

  8. c# websocket 心跳重连_websocket的简单使用

    1.maven项目,第一步需要配置jar包 org.springframework.boot spring-boot-starter-websocket 2.前台使用 var websocket = ...

  9. websocket binary 数据解析_WebSocket实现原理相关知识点

    WebSocket 是建立在 TCP/IP 协议之上,属于应用层的协议,而 Socket 是在应用层和传输层中的一个抽象层,它是将 TCP/IP 层的复杂操作抽象成几个简单的接口来提供给应用层调用.为 ...

最新文章

  1. “应付”大学作业,我花3小时写了一个“文本转手写”神器
  2. 斯坦福统计学习理论笔记:Percy Liang带你搞定「贼难」的理论基础
  3. 页面金额显示两位小数点问题
  4. 在ListBox中添加ToggleButton(有IsChecked属性)
  5. 【蓝桥杯省赛】冲刺练习题【动态规划】倒计时【08】天
  6. IntellijIDEA插件编写-删除/插入/替换文档内容
  7. 第1课 编程是一门技术_动动脑 第1题
  8. CentOS安装SonarQube7.9.1
  9. Java基础总结--1
  10. np.random.choice的用法
  11. Linux下解压.war文件
  12. IT人员必学最基础知识(一)——总括
  13. 调用百度语音合成API,Qt实现语音合成,Qt语音合成
  14. 辐射4 Hello World
  15. xdoj-81-字符串查找
  16. nodeJS实现简单网页爬虫功能
  17. ‘parent.relativePath‘ points at com.xxx instead of org.springframework.boot:spring-boot-starter的快速解决
  18. 幅相曲线渐近线_幅相曲线.ppt
  19. MySQL数据备份批处理
  20. OAuth认证(完整版)

热门文章

  1. postgresql基本操作
  2. Win7屏幕键盘 在哪 使用
  3. 用sql语句实现按时间求累计值
  4. 我把负载均衡讲出了花,领导却不给我涨工资
  5. 2021CVPR顶会冠军带你解密图像分割
  6. 实习生离职,HR恼羞成怒:我要全行业封杀你
  7. 推荐7个看似简约,实则惊艳的实用软件,建议收藏!
  8. android8.1内核编译,Android8.1.0安卓源码编译
  9. 百度搜索中台的FaaS化建设和智能化建设
  10. Keil5 STM32F系列 安装 安装包