PHP+Socket系列之实现websocket聊天室
本篇文章给大家带来了关于php+socket的相关知识,其中主要介绍了怎么使用php原生socket实现一个简易的web聊天室?感兴趣的朋友下面一起来看一下,希望对大家有帮助。
php原生socket实现websocket聊天室
前言
这篇文章实现了使用php原生socket实现了一个简易的web聊天室,最终代码在文章最底部。
不出意外的话这应该是这个系列文章的最后一篇了,写这个系列文章时本以为是很简单的东西,但实际几篇写下来使我几乎通读了 workerman 的代码,所以永远不要眼高手低,一定还是要自己尝试,最好是写出来,才能证明自己真正的弄懂了一件事情
websocket介绍
webSocket 协议是一种网络通信协议,在 2008 年诞生,2011 年成为国际标准,RFC6455 定义了它的通信标准,如今所有浏览器都已支持了该协议。webSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工[^1]通讯的协议,服务器可以主动向客户端推送消息,客户端也可以主动向服务端发送消息。
webSocket 约定了一个通信协议的规范,通过握手机制,客户端(浏览器)和服务器(webserver)之间能建立一个类似 tcp 的连接,从而方便 cs 通信。
为什么需要websocket
HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了 请求 => 响应
模型,通信请求仅能由客户端发起,服务端对请求做出应答处理,这种通信模型有一个弊端:无法实现服务端主动向客户端发起消息。传统的 HTTP 请求,其并发能力都是依赖同时发起多个 TCP 连接访问服务器实现的而 websocket 则允许我们在一条 ws 连接上同时并发多个请求,即在 A 请求发出后 A 响应还未到达,就可以继续发出 B 请求。由于 TCP 的慢启动特性,以及连接本身的握手损耗,都使得 websocket 协议的这一特性有很大的效率提升。
特点
-
建立在 TCP 协议之上,服务端的实现相对比较容易
-
与 HTTP 协议有良好的兼容性,默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易被屏蔽,能通过各种 HTTP 代理服务器。
-
数据格式比较轻量,性能开销小,通信高效。
-
可以发送文本,也可以发送二进制数据。
-
没有同源限制,客户端可以与任意服务器进行通信。
-
协议标识符是 ws(如果加密则为 wss),服务地址就是 URL。
PHP实现websocket
客户端与服务端握手
websocket 协议在连接前需要握手[^2],通常握手方式有以下几种方式
-
基于 flash 的握手协议(不建议)
-
基于 md5 加密方式的握手协议
较早的握手方法,有两个 key,使用 md5 加密
-
基于 sha1 加密方式的握手协议
当前主要的握手协议,本文将以此协议为主
-
获取客户端上报的
Sec-WebSocket-key
-
拼接
key
+258EAFA5-E914-47DA-95CA-C5AB0DC85B11
-
对字符串做
SHA1
计算,再把得到的结果通过base64
加密,最后再返回给客户端
-
客户端请求信息如下:
GET /chat HTTP/1.1Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Origin: http://example.com Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13
登录后复制