PHP 简单实现webSocket
来源:互联网 发布:功夫监控软件 编辑:程序博客网 时间:2024/05/20 21:49
费话少说,用源代码说话
1)客户端实现
1 <html> 2 <head> 3 <meta charset="UTF-8"> 4 <title>Web sockets test</title> 5 <script src="jquery-min.js" type="text/javascript"></script> 6 <script type="text/javascript"> 7 var ws; 8 function ToggleConnectionClicked() { 9 try {10 ws = new WebSocket("ws://127.0.0.1:2000");//连接服务器 11 ws.onopen = function(event){alert("已经与服务器建立了连接\r\n当前连接状态:"+this.readyState);};12 ws.onmessage = function(event){alert("接收到服务器发送的数据:\r\n"+event.data);};13 ws.onclose = function(event){alert("已经与服务器断开连接\r\n当前连接状态:"+this.readyState);};14 ws.onerror = function(event){alert("WebSocket异常!");};15 } catch (ex) {16 alert(ex.message); 17 }18 };19 20 function SendData() {21 try{22 var content = document.getElementById("content").value;23 if(content){24 ws.send(content);25 }26 27 }catch(ex){28 alert(ex.message);29 }30 };31 32 function seestate(){33 alert(ws.readyState);34 }35 36 </script>37 </head>38 <body>39 <button id='ToggleConnection' type="button" onclick='ToggleConnectionClicked();'>连接服务器</button><br /><br />40 <textarea id="content" ></textarea>41 <button id='ToggleConnection' type="button" onclick='SendData();'>发送我的名字:beston</button><br /><br />42 <button id='ToggleConnection' type="button" onclick='seestate();'>查看状态</button><br /><br />43 44 </body>45 </html>
2)服务器端实现
1 class WS { 2 var $master; // 连接 server 的 client 3 var $sockets = array(); // 不同状态的 socket 管理 4 var $handshake = false; // 判断是否握手 5 6 function __construct($address, $port){ 7 // 建立一个 socket 套接字 8 $this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) 9 or die("socket_create() failed"); 10 socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) 11 or die("socket_option() failed"); 12 socket_bind($this->master, $address, $port) 13 or die("socket_bind() failed"); 14 socket_listen($this->master, 2) 15 or die("socket_listen() failed"); 16 17 $this->sockets[] = $this->master; 18 19 // debug 20 echo("Master socket : ".$this->master."\n"); 21 22 while(true) { 23 //自动选择来消息的 socket 如果是握手 自动选择主机 24 $write = NULL; 25 $except = NULL; 26 socket_select($this->sockets, $write, $except, NULL); 27 28 foreach ($this->sockets as $socket) { 29 //连接主机的 client 30 if ($socket == $this->master){ 31 $client = socket_accept($this->master); 32 if ($client < 0) { 33 // debug 34 echo "socket_accept() failed"; 35 continue; 36 } else { 37 //connect($client); 38 array_push($this->sockets, $client); 39 echo "connect client\n"; 40 } 41 } else { 42 $bytes = @socket_recv($socket,$buffer,2048,0); 43 print_r($buffer); 44 if($bytes == 0) return; 45 if (!$this->handshake) { 46 // 如果没有握手,先握手回应 47 $this->doHandShake($socket, $buffer); 48 echo "shakeHands\n"; 49 } else { 50 51 // 如果已经握手,直接接受数据,并处理 52 $buffer = $this->decode($buffer); 53 //process($socket, $buffer); 54 echo "send file\n"; 55 } 56 } 57 } 58 } 59 } 60 61 function dohandshake($socket, $req) 62 { 63 // 获取加密key 64 $acceptKey = $this->encry($req); 65 $upgrade = "HTTP/1.1 101 Switching Protocols\r\n" . 66 "Upgrade: websocket\r\n" . 67 "Connection: Upgrade\r\n" . 68 "Sec-WebSocket-Accept: " . $acceptKey . "\r\n" . 69 "\r\n"; 70 71 echo "dohandshake ".$upgrade.chr(0); 72 // 写入socket 73 socket_write($socket,$upgrade.chr(0), strlen($upgrade.chr(0))); 74 // 标记握手已经成功,下次接受数据采用数据帧格式 75 $this->handshake = true; 76 } 77 78 79 function encry($req) 80 { 81 $key = $this->getKey($req); 82 $mask = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 83 84 return base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); 85 } 86 87 function getKey($req) 88 { 89 $key = null; 90 if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $req, $match)) { 91 $key = $match[1]; 92 } 93 return $key; 94 } 95 96 // 解析数据帧 97 function decode($buffer) 98 { 99 $len = $masks = $data = $decoded = null;100 $len = ord($buffer[1]) & 127;101 102 if ($len === 126) {103 $masks = substr($buffer, 4, 4);104 $data = substr($buffer, 8);105 } else if ($len === 127) {106 $masks = substr($buffer, 10, 4);107 $data = substr($buffer, 14);108 } else {109 $masks = substr($buffer, 2, 4);110 $data = substr($buffer, 6);111 }112 for ($index = 0; $index < strlen($data); $index++) {113 $decoded .= $data[$index] ^ $masks[$index % 4];114 }115 return $decoded;116 }117 118 // 返回帧信息处理119 function frame($s) 120 {121 $a = str_split($s, 125);122 if (count($a) == 1) {123 return "\x81" . chr(strlen($a[0])) . $a[0];124 }125 $ns = "";126 foreach ($a as $o) {127 $ns .= "\x81" . chr(strlen($o)) . $o;128 }129 return $ns;130 }131 132 // 返回数据133 function send($client, $msg)134 {135 $msg = $this->frame($msg);136 socket_write($client, $msg, strlen($msg));137 }138 }
测试 $ws = new WS("127.0.0.1",2000);
阅读全文
0 0
- PHP 简单实现webSocket
- PHP 简单实现webSocket
- php websocket 简单DEMO
- html5 websocket 简单实现
- golang简单实现Websocket
- java简单实现websocket
- 简单的websocket实现
- WebSocket简单实现
- WebSocket 的 PHP 实现 - phpwebsocket
- php 异步websocket客户端实现
- erlang实现websocket简单示例
- websocket实现简单的聊天室
- Html5,Java WebSocket简单实现
- websocket 简介、实现简单聊天室
- websocket实现简单聊天程序
- WebSocket简单介绍 Java后端WebSocket的Tomcat实现
- 利用Swoole实现PHP+websocket 聊天室
- 利用Swoole实现PHP+websocket 聊天室
- 从 HTTP 到 HTTPS
- 用Let's Encrypt实现Https(Windows环境+Tomcat+Java)
- Approaching (Almost) Any Machine Learning Problem
- windows下部署免费ssl证书(letsencrypt)
- 【转】为什么要报考系统架构设计师考试
- PHP 简单实现webSocket
- mysql运维
- 【Linux】Linux中常用操作命令
- 疑惑2
- caffe学习笔记5:其它常用层及其参数
- 如何胜任一个小型公司的技术总监?
- 免费SSL证书
- php结合redis实现高并发下的抢购、秒杀功能
- MySQL 性能测试经验