天天看点

细说websocket - php篇

下面我画了一个图演示 client 和 server 之间建立 websocket 连接时握手部分,这个部分在 node 中可以十分轻松的完成,因为 node 提供的 net 模块已经对 socket 套接字做了封装处理,开发者使用的时候只需要考虑数据的交互而不用处理连接的建立。而 php 没有,从 socket 的连接、建立、绑定、监听等,这些都需要我们自己去操作,所以有必要拿出来再说一说。

我们往常看到的请求是这个样子,当这东西到了服务器端,我们可以通过一些代码库直接拿到这些信息。

WebSocket 连接是由客户端主动发起的,所以一切要从客户端出发。第一步是要解析拿到客户端发过来的 Sec-WebSocket-Key 字符串。

关于 socket 套接字的建立,相信很多大学修过计算机网络的人都知道了,下面是一张连接建立的过程:

细说websocket - php篇

相比 node,这个地方的处理实在是太麻烦了,上面几行代码并未建立连接,只不过这些代码是建立一个 socket 套接字必须要写的东西。由于处理过程稍微有复杂,所以我把各种处理写进了一个类中,方便管理和调用。

细说websocket - php篇

 demo.php 握手连接测试代码

上面这段代码是经过我调试了的,没太大的问题,如果想测试的话,可以在 cmd 命令行中键入<code>php /path/to/demo.php</code>;当然,上面只是一个类,如果要测试的话,还得新建一个实例。

客户端代码可以稍微简单点:

运行服务器代码,当客户端连接的时候,我们可以看到:

细说websocket - php篇

这里比较简单,直接正则匹配,websocket 信息头一定包含 Sec-WebSocket-Key,所以我们匹配起来也比较快捷~

将 SHA-1 加密后的字符串再进行一次 base64 加密。如果加密算法错误,客户端在进行校检的时候会直接报错:

细说websocket - php篇

这里千万要注意,每一个请求和相应的格式,最后有一个空行,也就是 <code>\r\n</code>,开始测试的时候把这东西给弄丢了,纠结了半天。

细说websocket - php篇

当客户端成功校检key后,会触发 onopen 函数:

细说websocket - php篇

这里涉及的编码问题在前文中已经提到过了,这里就不赘述,php 对字符处理的函数太多了,也记得不是特别清楚,这里就没有详细的介绍解码程序,直接把客户端发送的数据原样返回,可以算是一个聊天室的模式吧。

客户端代码:

在连通之后发送数据,服务器原样返回:

细说websocket - php篇

客户端在握手时的请求中有<code>Sec-WebSocket-Version: 13</code>,这样的版本标识,这个是一个升级版本,现在的浏览器都是使用的这个版本。而以前的版本在数据加密的部分更加麻烦,它会发送两个key:

如果是这种版本(比较老,已经没在使用了),需要通过下面的方式获取

只能无限吐槽这种验证方式!相比 nodeJs 的 websocket 操作方式:

多么简洁,多么方便!有谁还愿意使用 php 呢。。。。

本文没有给出 decodeFrame 这样数据帧解析代码,前文中给出了数据帧的格式,解析纯属体力活。

本文转自Barret Lee博客园博客,原文链接:http://www.cnblogs.com/hustskyking/p/websocket-with-php.html,如需转载请自行联系原作者