1,核心概念:
websocket协议是http的升级版。
2,一次握手
websocket在创建连接时会先向服务端发送一个普通的http请求,大致消息为:
GET / HTTP/1.1
Host: localhost:1234
User-Agent: Mozilla/5.0 (WindowsNT 10.0; WOW64; rv:59.0) Gecko/20100101 Firefox/59.0
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin:http://xxx.xxx.xxx
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: 3hfEc+Te7n7FSrLBsN59ig==
Connection: keep-alive,Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
相比较普通的http请求多了
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: 3hfEc+Te7n7FSrLBsN59ig==
Connection: keep-alive,Upgrade
Upgrade: websocket
服务端通过
Upgrade: websocket
判断是否为websocket请求通过生成新的key,并拼接成新的响应消息
$new_key = base64_encode(sha1($head['Sec-WebSocket-Key']."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Sec-WebSocket-Version: 13
Connection: Upgrade
Sec-WebSocket-Accept:new-key
完成一次握手双方建立通信通道
完整的服务案例<转载的>
class WebSocketServer{
private $sockets;//所有socket连接池包括服务端socket
private $users;//所有连接用户
private $server;//服务端 socket
public function __construct($ip,$port){
$this->server=socket_create(AF_INET,SOCK_STREAM,0);
$this->sockets=array($this->server);
$this->users=array();
socket_bind($this->server,$ip,$port);
socket_listen($this->server,3);
echo "[*]Listening:".$ip.":".$port."\n";
}
public function run(){
$write=NULL;
$except=NULL;
while (true){
$active_sockets=$this->sockets;
socket_select($active_sockets,$write,$except,NULL);
//这个函数很重要
foreach ($active_sockets as $socket){
if ($socket==$this->server){
//服务端 socket可读说明有新用户连接
$user=socket_accept($this->server);
$k