PHP websocket学习笔记

本文阅读 2 分钟
首页 PHP笔记 正文
  1. <?php
  2. <?php
  3. class Ws {
  4. // 服务器端的socket
  5. private $mainSocket;
  6. // socket队列
  7. public $socketList = [];
  8. // 连接事件
  9. public $onConnection;
  10. // 会话事件
  11. public $onMessage;
  12. // 关闭事件
  13. public $onClose;
  14. // 构造函数
  15. public function __construct() {
  16. // 创建socket
  17. $this->mainSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  18. // IP和端口重用
  19. socket_set_option($this->mainSocket, SOL_SOCKET, SO_REUSEADDR, 1);
  20. // 绑定
  21. socket_bind($this->mainSocket, '0.0.0.0', 6060);
  22. // 监听
  23. socket_listen($this->mainSocket, 5);
  24. // 把服务器端的socket存入socket队列
  25. $this-&gt;socketList[(int)$this->mainSocket] = $this->mainSocket;
  26. }
  27. // 运行
  28. public function run() {
  29. // 让服务不停止
  30. while (true) {
  31. $read&nbsp;&nbsp;=&nbsp;$this->socketList;
  32. $write&nbsp;=&nbsp;$except = null;
  33. // 删除不活跃的socket
  34. $status&nbsp;=&nbsp;socket_select($read, $write,&nbsp;$except, null);
  35. if (!$status) continue;
  36. foreach ($read&nbsp;as&nbsp;$socket) {
  37. // 第一次来访问
  38. if ($this-&gt;mainSocket&nbsp;==&nbsp;$socket) {
  39. // 得到客户端的socket
  40. $clientSocket&nbsp;=&nbsp;socket_accept($socket);
  41. // 获取客户端头信息进行握手操作
  42. $headData&nbsp;=&nbsp;socket_read($clientSocket, 8000);
  43. handshaking($headData,&nbsp;$clientSocket);
  44. socket_getpeername($clientSocket,&nbsp;$addr, $port);
  45. // 把客户端的一个socket存入队列中
  46. $this-&gt;socketList[(int)$clientSocket] = $clientSocket;
  47. $read[(int)$clientSocket] = $clientSocket;
  48. // 删除掉
  49. unset($read[(int)$this->mainSocket]);
  50. // 注册一个事件
  51. if ($this->onConnection) {
  52. call_user_func($this-&gt;onConnection,&nbsp;$clientSocket);
  53. }
  54. } else {
  55. // 获得客户发送过来的数据
  56. $buf&nbsp;=&nbsp;socket_read($socket, 8000);
  57. // 关闭或异常
  58. if ($buf&nbsp;===&nbsp;&#39;&#39;&nbsp;||&nbsp;$buf === false) {
  59. // 删除掉队列它socket
  60. unset($read[(int)$socket]);
  61. unset($this-&gt;socketList[(int)$socket]);
  62. if ($this->onClose){
  63. call_user_func($this->onClose);
  64. }
  65. socket_close($socket);
  66. continue;
  67. }else{
  68. if ($this->onMessage){
  69. call_user_func($this-&gt;onMessage,$socket,$buf);
  70. }
  71. }
  72. }
  73. }//End foreach
  74. }// End while
  75. }//End run
  76. }
  77. $server = new Ws();
  78. // 连接
  79. $server-&gt;onConnection&nbsp;=&nbsp;function&nbsp;($socket){
  80. $msg&nbsp;=&nbsp;(int)$socket."欢迎进入web60聊天室 !";
  81. socket_write($socket,enmask($msg));
  82. };
  83. // 会话
  84. $server-&gt;onMessage&nbsp;=&nbsp;function&nbsp;($socket,$data){
  85. $msg&nbsp;=&nbsp;unmask($data);
  86. // 广播给所有人 聊天室
  87. broadcast($msg);
  88. };
  89. $server->run();
  90. /**
  91. * @param $msg 广播的消息
  92. */
  93. function broadcast($msg){
  94. global $server;
  95. foreach ($server-&gt;socketList&nbsp;as&nbsp;$socket){
  96. $tmp&nbsp;=&nbsp;enmask((int)$socket.'说:'.$msg);
  97. @socket_write($socket,$tmp);
  98. }
  99. }
  100. /**
  101. * @param $header 客户端头信息
  102. * @param $activeSocket 客户端的socket对象
  103. */
  104. function handshaking($header,&nbsp;$activeSocket) {
  105. preg_match("/Sec-WebSocket-Key:&nbsp;(.+)rn/", $header,&nbsp;$matchs);
  106. $key&nbsp;&nbsp;=&nbsp;base64_encode(sha1($matchs[1] . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
  107. $head = "HTTP/1.1 101 Switching Protocolsrn";
  108. $head .= "Upgrade: websocketrn"; // 告诉这个websocket客户端可以把这个协议升级为websocket协议
  109. $head .= "Connection: Upgradern"; // 升级这个通信协议
  110. $head&nbsp;.=&nbsp;&quot;Sec-WebSocket-Accept:&nbsp;{$key}rnrn"; // 最后的一定要有两个回车
  111. // 握手响应协议信息返回给浏览器
  112. socket_write($activeSocket,&nbsp;$head);
  113. }
  114. //解码数据
  115. function unmask($text) {
  116. $length&nbsp;=&nbsp;ord($text[1]) & 127;
  117. if ($length == 126) {
  118. $masks&nbsp;=&nbsp;substr($text, 4, 4);
  119. $data&nbsp;&nbsp;=&nbsp;substr($text, 8);
  120. } elseif ($length == 127) {
  121. $masks&nbsp;=&nbsp;substr($text, 10, 4);
  122. $data&nbsp;&nbsp;=&nbsp;substr($text, 14);
  123. } else {
  124. $masks&nbsp;=&nbsp;substr($text, 2, 4);
  125. $data&nbsp;&nbsp;=&nbsp;substr($text, 6);
  126. }
  127. $text = "";
  128. for ($i&nbsp;=&nbsp;0;&nbsp;$i < strlen($data);&nbsp;++$i) {
  129. $text&nbsp;.=&nbsp;$data[$i]&nbsp;^&nbsp;$masks[$i % 4];
  130. }
  131. return $text;
  132. }
  133. // 加码数据
  134. function enmask($str) {
  135. $a&nbsp;&nbsp;=&nbsp;str_split($str, 125);
  136. $ns = "";
  137. foreach ($a&nbsp;as&nbsp;$o) {
  138. $ns&nbsp;.=&nbsp;&quot;\x81&quot;&nbsp;.&nbsp;chr(strlen($o)) . $o;
  139. }
  140. return $ns;
  141. }
  142. ?>
解压密码: detechn或detechn.com

免责声明

本站所有资源出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。

本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户自行鉴别,做一个有主见和判断力的用户。

本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。

PHP基本语法学习
« 上一篇 07-14
PHP 汉字转拼音 [包含20902个基本汉字+5059生僻字]
下一篇 » 07-14

发表评论

惪特博客
  • 文章总数:
    18497 篇
  • 评论总数:
    53345 条
  • 标签总数:
    8873 个
  • 总浏览量:
    23015027 次
  • 最后更新:
    3月27日

最多点赞

随便看看

标签TAG