0

0

使用php创建WebSocket服务

php中文网

php中文网

发布时间:2016-07-25 08:50:47

|

1996人浏览过

|

来源于php中文网

原创

执行方法:
首先先修改server.php与index.html的ip
通过命令行执行 [php路径]\php.exe "[文件路径]\server.php"
然后通过浏览器打开index.html
  1. include 'websocket.class.php';
  2. $config=array(
  3. 'address'=>'192.168.0.200',
  4. 'port'=>'8000',
  5. 'event'=>'WSevent',//回调函数的函数名
  6. 'log'=>true,
  7. );
  8. $websocket = new websocket($config);
  9. $websocket->run();
  10. function WSevent($type,$event){
  11. global $websocket;
  12. if('in'==$type){
  13. $websocket->log('客户进入id:'.$event['k']);
  14. }elseif('out'==$type){
  15. $websocket->log('客户退出id:'.$event['k']);
  16. }elseif('msg'==$type){
  17. $websocket->log($event['k'].'消息:'.$event['msg']);
  18. roboot($event['sign'],$event['msg']);
  19. }
  20. }
  21. function roboot($sign,$t){
  22. global $websocket;
  23. switch ($t)
  24. {
  25. case 'hello':
  26. $show='hello,GIt @ OSC';
  27. break;
  28. case 'name':
  29. $show='Robot';
  30. break;
  31. case 'time':
  32. $show='当前时间:'.date('Y-m-d H:i:s');
  33. break;
  34. case '再见':
  35. $show='( ^_^ )/~~拜拜';
  36. $websocket->write($sign,'Robot:'.$show);
  37. $websocket->close($sign);
  38. return;
  39. break;
  40. case '天王盖地虎':
  41. $array = array('小鸡炖蘑菇','宝塔震河妖','粒粒皆辛苦');
  42. $show = $array[rand(0,2)];
  43. break;
  44. default:
  45. $show='( ⊙o⊙?)不懂,你可以尝试说:hello,name,time,再见,天王盖地虎.';
  46. }
  47. $websocket->write($sign,'Robot:'.$show);
  48. }
  49. ?>
复制代码
  1. websocket_TEST
复制代码
  1. /*
  2. 创建类websocket($config);
  3. $config结构:
  4. $config=array(
  5. 'address'=>'192.168.0.200',//绑定地址
  6. 'port'=>'8000',//绑定端口
  7. 'event'=>'WSevent',//回调函数的函数名
  8. 'log'=>true,//命令行显示记录
  9. );
  10. 回调函数返回数据格式
  11. function WSevent($type,$event)
  12. $type字符串 事件类型有以下三种
  13. in 客户端进入
  14. out 客户端断开
  15. msg 客户端消息到达
  16. 均为小写
  17. $event 数组
  18. $event['k']内置用户列表的userid;
  19. $event['sign']客户标示
  20. $event['msg']收到的消息 $type='msg'时才有该信息
  21. 方法:
  22. run()运行
  23. search(标示)遍历取得该标示的id
  24. close(标示)断开连接
  25. write(标示,信息)推送信息
  26. idwrite(id,信息)推送信息
  27. 属性:
  28. $users 客户列表
  29. 结构:
  30. $users=array(
  31. [用户id]=>array('socket'=>[标示],'hand'=[是否握手-布尔值]),
  32. [用户id]=>arr.....
  33. )
  34. */
  35. class websocket{
  36. public $log;
  37. public $event;
  38. public $signets;
  39. public $users;
  40. public $master;
  41. public function __construct($config){
  42. if (substr(php_sapi_name(), 0, 3) !== 'cli') {
  43. die("请通过命令行模式运行!");
  44. }
  45. error_reporting(E_ALL);
  46. set_time_limit(0);
  47. ob_implicit_flush();
  48. $this->event = $config['event'];
  49. $this->log = $config['log'];
  50. $this->master=$this->WebSocket($config['address'], $config['port']);
  51. $this->sockets=array('s'=>$this->master);
  52. }
  53. function WebSocket($address,$port){
  54. $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  55. socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
  56. socket_bind($server, $address, $port);
  57. socket_listen($server);
  58. $this->log('开始监听: '.$address.' : '.$port);
  59. return $server;
  60. }
  61. function run(){
  62. while(true){
  63. $changes=$this->sockets;
  64. @socket_select($changes,$write=NULL,$except=NULL,NULL);
  65. foreach($changes as $sign){
  66. if($sign==$this->master){
  67. $client=socket_accept($this->master);
  68. $this->sockets[]=$client;
  69. $user = array(
  70. 'socket'=>$client,
  71. 'hand'=>false,
  72. );
  73. $this->users[] = $user;
  74. $k=$this->search($client);
  75. $eventreturn = array('k'=>$k,'sign'=>$sign);
  76. $this->eventoutput('in',$eventreturn);
  77. }else{
  78. $len=socket_recv($sign,$buffer,2048,0);
  79. $k=$this->search($sign);
  80. $user=$this->users[$k];
  81. if($len $this->close($sign);
  82. $eventreturn = array('k'=>$k,'sign'=>$sign);
  83. $this->eventoutput('out',$eventreturn);
  84. continue;
  85. }
  86. if(!$this->users[$k]['hand']){//没有握手进行握手
  87. $this->handshake($k,$buffer);
  88. }else{
  89. $buffer = $this->uncode($buffer);
  90. $eventreturn = array('k'=>$k,'sign'=>$sign,'msg'=>$buffer);
  91. $this->eventoutput('msg',$eventreturn);
  92. }
  93. }
  94. }
  95. }
  96. }
  97. function search($sign){//通过标示遍历获取id
  98. foreach ($this->users as $k=>$v){
  99. if($sign==$v['socket'])
  100. return $k;
  101. }
  102. return false;
  103. }
  104. function close($sign){//通过标示断开连接
  105. $k=array_search($sign, $this->sockets);
  106. socket_close($sign);
  107. unset($this->sockets[$k]);
  108. unset($this->users[$k]);
  109. }
  110. function handshake($k,$buffer){
  111. $buf = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18);
  112. $key = trim(substr($buf,0,strpos($buf,"\r\n")));
  113. $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
  114. $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
  115. $new_message .= "Upgrade: websocket\r\n";
  116. $new_message .= "Sec-WebSocket-Version: 13\r\n";
  117. $new_message .= "Connection: Upgrade\r\n";
  118. $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
  119. socket_write($this->users[$k]['socket'],$new_message,strlen($new_message));
  120. $this->users[$k]['hand']=true;
  121. return true;
  122. }
  123. function uncode($str){
  124. $mask = array();
  125. $data = '';
  126. $msg = unpack('H*',$str);
  127. $head = substr($msg[1],0,2);
  128. if (hexdec($head小贝) === 8) {
  129. $data = false;
  130. }else if (hexdec($head小贝) === 1){
  131. $mask[] = hexdec(substr($msg[1],4,2));
  132. $mask[] = hexdec(substr($msg[1],6,2));
  133. $mask[] = hexdec(substr($msg[1],8,2));
  134. $mask[] = hexdec(substr($msg[1],10,2));
  135. $s = 12;
  136. $e = strlen($msg[1])-2;
  137. $n = 0;
  138. for ($i=$s; $i $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2)));
  139. $n++;
  140. }
  141. }
  142. return $data;
  143. }
  144. function code($msg){
  145. $msg = preg_replace(array('/\r$/','/\n$/','/\r\n$/',), '', $msg);
  146. $frame = array();
  147. $frame[0] = '81';
  148. $len = strlen($msg);
  149. $frame[1] = $len $frame[2] = $this->ord_hex($msg);
  150. $data = implode('',$frame);
  151. return pack("H*", $data);
  152. }
  153. function ord_hex($data) {
  154. $msg = '';
  155. $l = strlen($data);
  156. for ($i= 0; $i $msg .= dechex(ord($data{$i}));
  157. }
  158. return $msg;
  159. }
  160. function idwrite($id,$t){//通过id推送信息
  161. if(!$this->users[$id]['socket']){return false;}//没有这个标示
  162. $t=$this->code($t);
  163. return socket_write($this->users[$id]['socket'],$t,strlen($t));
  164. }
  165. function write($k,$t){//通过标示推送信息
  166. $t=$this->code($t);
  167. return socket_write($k,$t,strlen($t));
  168. }
  169. function eventoutput($type,$event){//事件回调
  170. call_user_func($this->event,$type,$event);
  171. }
  172. function log($t){//控制台输出
  173. if($this->log){
  174. $t=$t."\r\n";
  175. fwrite(STDOUT, iconv('utf-8','gbk//IGNORE',$t));
  176. }
  177. }
  178. }
复制代码


相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

4

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

3

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

10

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

15

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

42

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

7

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

9

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

6

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python 教程
Python 教程

共137课时 | 7.4万人学习

PHP课程
PHP课程

共137课时 | 8.7万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号