| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> PHP知识库 -> 即时通讯源码php开源版下载附安装教程+演示 -> 正文阅读 |
|
[PHP知识库]即时通讯源码php开源版下载附安装教程+演示 |
1、引言有关Web端即时通讯技术的文章我已整理过很多篇,阅读过的读者可能都很熟悉,早期的Web端即时通讯方案,受限于Web客户端的技术限制,想实现真正的“即时”通信,难度相当大。 源码演示与下载地址:ym.ws58.net 传统的Web端即时通讯技术从短轮询到长连询,再到Comet技术,在如此原始的HTML标准之下,为了实现所谓的“即时”通信,技术上可谓绞尽脑汁,极尽所能。 自从HTML5标准发布之后,WebSocket这类技术横空出世,实现Web端即时通讯技术的便利性大大提前,以往想都不敢想的真正全双工实时通信,如此早已成为可能。 本文将专门介绍WebSocket、socket.io、SSE这几种现代的Web端即时通讯技术,从适用场景到技术原理,通俗又不失深度的文字,特别适合对Web端即时通讯技术有一定了解,且想深入学习WebSocket等现代Web端“实时”通信技术,却又不想花时间去深读枯燥的IETF技术手册的读者。 3、知识预备如果你对Web端即时通讯技术的前世今生不曾了解,建议先读以下文章:
如果你对本文将要介绍的技术已有了解,建议进行专项学习,以便深入掌握:
4、WebSocket在这里不打算详细介绍整个WebSocket协议的内容,根据我本人以前协议的学习思路,我挑重点使用问答方式来介绍该协议,这样读起来就不那么枯燥。 4.1 基本情况 协议运行在OSI的哪层? 应用层,WebSocket协议是一个独立的基于TCP的协议。 它与HTTP唯一的关系是它的握手是由HTTP服务器解释为一个Upgrade请求。 协议运行的标准端口号是多少? 默认情况下,WebSocket协议使用端口80用于常规的WebSocket连接、端口443用于WebSocket连接的在传输层安全(TLS)RFC2818之上的隧道化口。 4.2 协议是如何工作的? 协议的工作流程可以参考下图: 其中帧的一些重要字段需要解释一下:
关于Sec-WebSocket-Key和Sec-WebSocket-Accept的计算是这样的:
用代码就是实现如下:
至于为什么需要这么一个步骤,可以参考《理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性》一文。 引用如下:
作用大致归纳如下:
强调:Sec-WebSocket-Key/Sec-WebSocket-Accept 的换算,只能带来基本的保障,但连接是否安全、数据是否安全、客户端/服务端是否合法的 ws客户端、ws服务端,其实并没有实际性的保证。 4.3 协议传输的帧格式是什么? 帧格式定义的格式如下: 各个字段的解释如下: 源码演示与下载地址:ym.ws58.net
更多细节请参考RFC6455-数据帧,这里不作赘述。 针对上面的各个字段的介绍,有一个Mask的需要说一下。 掩码键(Masking-key)是由客户端挑选出来的32位的随机数。掩码操作不会影响数据载荷的长度。 掩码、反掩码操作都采用如下算法。 首先,假设:
算法描述为:?original-octet-i 与 masking-key-octet-j 异或后,得到 transformed-octet-i。 即:?j = i MOD 4 transformed-octet-i = original-octet-i XOR masking-key-octet-j 用代码实现:
解掩码是反过来的操作:
同样的为什么需要掩码操作,也可以参考之前的那篇文章:《理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性》,完整的我就不列举了。 需要注意的重点,我引用一下:
5、socket5.1 本节引言 源码演示与下载地址:ym.ws58.net 介绍完上一节WebSocket协议,我们把视线转移到现代Web端即时通讯技术的第二个利器:socket.io。 估计有读者就会问,WebSocket和socket.io有啥区别啊? 在了解socket.io之前,我们先聊聊传统Web端即时通讯“长连接”技术的实现背景。 5.2 传统Web长连接的技术实现背景 在现实的Web端产品中,并不是所有的Web客户端都支持长连接的,或者换句话说,在WebSocket协议出来之前,是三种方式去实现WebSocket类似的功能的。 这三种方式是:
那么如果单纯地使用WebSocket的话,那些不支持的客户端怎么办呢?难道直接放弃掉? 当然不是。Guillermo Rauch大神写了socket.io这个库,对WebSocket进行封装,从而让长连接满足所有的场景,不过当然得配合使用对应的客户端代码。 socket.io将会使用特性检测的方式来决定以websocket/ajax长轮询/flash等方式建立连接。 那么socket.io是如何做到这些的呢? 我们带着以下几个问题去学习:
如果有童鞋对上述问题已经清楚,想必就没有往下读的必要了。 5.3 socket.io的介绍 通过前面章节,读者们都知道了WebSocket的功能,那么socket.io相对于WebSocket,在此基础上封装了一些什么新东西呢? socket.io其实是有一套封装了websocket的协议,叫做engine.io协议,在此协议上实现了一套底层双向通信的引擎Engine.io。 而socket.io则是建立在engine.io上的一个应用层框架而已。所以我们研究的重点便是engine.io协议。 在socket.io的README中提到了其实现的一些新特性(回答了问题一):
注意:Socket.IO不是WebSocket的实现,虽然 Socket.IO确实在可能的情况下会去使用WebSocket作为一个transport,但是它添加了很多元数据到每一个报文中:报文的类型以及namespace和ack Id。这也是为什么标准WebSocket客户端不能够成功连接上 Socket.IO 服务器,同样一个 Socket.IO 客户端也连接不上标准WebSocket服务器的原因。 5.4 engine.io协议介绍 完整的engine.io协议的握手过程如下图: 当前engine.io协议的版本是3,我们根据上图来大致介绍一下engine.io协议。 5.4.1)engine.io协议请求字段: 我们看到的是请求的url和WebSocket不大一样,解释一下:
除了上述的3个字段,协议还描述了下面几个字段:
另外engine.io默认的path是 /engine.io,socket.io在初始化的时候设置为了 /socket.io,所以大家看到的path就都是 /socket.io 了:
5.4.2)数据包编码要求: engine.io协议的数据包编码有自己的一套格式,在协议介绍上engine.io-protocol,定义了两种编码类型: packet和payload。 一个编码过的packet是下面这种格式:
然后协议定义了下面几种packet type(采用数字进行标识):
那payload也有对应的格式要求:
注意:payload的编码要求不适用于WebSocket的通信。 针对上面的编码要求,我们随便举个例子. 之前在第一条polling请求的时候,服务端编码发送了这个数据:
根据上面的知识,我们知道第一次服务端会发送一个open的数据包。 所以组装出来的packet是:
然后服务端会告知客户端去尝试升级到websocket,并且告知对应的sid。 于是整合后便是:
接着根据payload的编码格式,因为是string,且长度是97个字节。 所以是:
接着第二部分数据是message包类型,并且数据是0,所以是40,长度为2字节,所以是2:40,最后就拼成刚才大家看到的结果。 注意:
5.5 升级协议的必备过程 协议定义了transport升级到websocket需要经历一个必须的过程。 如下图: WebSocket的测试开始于发送probe,如果服务器也响应probe的话,客户端就必须发送一个upgrade包。 为了确保不会丢包,只有在当前transport的所有buffer被刷新并且transport被认为paused的时候才可以发送upgrade包。服务端收到upgrade包的时候,服务端必须假设这是一个新的通道并发送所有已存的缓存到这个通道上 在Chrome上的效果如下: 5.6 engine.io的代码实现 熟悉了engine.io协议之后,我们看看代码是怎么实现主流程的。 客户端的engine.io的主要实现流程我们在上面文字介绍了。 结合代码engine.io,画了这么一个客户端流程图: 服务端的代码和客户端非常相似,其实现流程图如下: 6、SSE6.1 本节引言 本文前两节分析了WebSocket和socket.io,现在我们来看看SSE。 很多人也许好奇,有了WebSocket这种实时通信,为什么还需要SSE呢? 答案其实很简单:那就是SSE其实是单向通信,而WebSocket是双向通信。 比如:在股票行情、新闻推送的这种只需要服务器发送消息给客户端场景中,使用SSE可能更加合适。 另外:SSE是使用HTTP传输的,这意味着我们不需要一个特殊的协议或者额外的实现就可以使用。而WebSocket要求全双工连接和一个新的WebSocket服务器去处理。加上SSE在设计的时候就有一些WebSocket没有的特性,比如自动重连接、event IDs、以及发送随机事件的能力,所以各有各的特长,我们需要根据实际应用场景,去选择不同的应用方案。 6.2 SSE介绍 SSE的简单模型是:一个客户端去从服务器端订阅一条“流”,之后服务端可以发送消息给客户端直到服务端或者客户端关闭该“流”,所以SSE全称叫“server-sent-event”。 相比以前的轮询,SSE可以为B2C带来更高的效率。 有一张图片画出了二者的区别: 6.3 SSE数据帧的格式 SSE必须编码成utf-8的格式,消息的每个字段使用"\n"来做分割,并且需要下面4个规范定义好的字段。 这4个字段是:
下图是通过wireshark抓包得到的数据包的原始格式: 6.4 SSE通信过程 SSE的通信过程比较简单,底层的一些实现都被浏览器给封装好了,包括数据的处理。 大致流程如下: 在浏览器中截图如下: 携带的数据是JSON格式的,浏览器都帮你整合成为一个Object: 在wireshark中,其通信流程如下。 发送请求: 得到响应: 在开始推送信息流之前,服务器还会发送一个客户端会忽略掉的包,这个具体原因不清楚: 断开连接后的重传: 6.5 SSE的简单使用示例 浏览器端的使用:
服务端的使用:
更多API使用和demo介绍分别参考:SSE API、demo代码。 6.6 兼容性及缺点 兼容性: ▲ 上图来自 网络 缺点:
|
|
PHP知识库 最新文章 |
Laravel 下实现 Google 2fa 验证 |
UUCTF WP |
DASCTF10月 web |
XAMPP任意命令执行提升权限漏洞(CVE-2020- |
[GYCTF2020]Easyphp |
iwebsec靶场 代码执行关卡通关笔记 |
多个线程同步执行,多个线程依次执行,多个 |
php 没事记录下常用方法 (TP5.1) |
php之jwt |
2021-09-18 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 7:37:25- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |