无为清净楼资源网 Design By www.qnjia.com

本文实例讲述了PHP实现websocket通信的方法。分享给大家供大家参考,具体如下:

执行方法:

首先先修改server.php与index.html的ip
通过命令行执行 [php路径]\php.exe "[文件路径]\server.php"
然后通过浏览器打开index.html

server.php

<"htmlcode">
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>websocket_TEST</title>
</head>
<body>
<textarea class="log" style="width: 100%; height: 500px;">
=======websocket======
</textarea>
<input type="button" value="连接" onClick="link()">
<input type="button" value="断开" onClick="dis()">
<input type="text" id="text">
<input type="button" value="发送" onClick="send()">
<script src="/UploadFiles/2021-04-02/jquery.min.js">

websocket.class.php

<"请通过命令行模式运行!");
    }
    error_reporting(E_ALL);
    set_time_limit(0);
    ob_implicit_flush();
    $this->event = $config['event'];
    $this->log = $config['log'];
    $this->master=$this->WebSocket($config['address'], $config['port']);
    $this->sockets=array('s'=>$this->master);
  }
  function WebSocket($address,$port){
    $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
    socket_bind($server, $address, $port);
    socket_listen($server);
    $this->log('开始监听: '.$address.' : '.$port);
    return $server;
  }
 function run(){
  while(true){
   $changes=$this->sockets;
   @socket_select($changes,$write=NULL,$except=NULL,NULL);
   foreach($changes as $sign){
    if($sign==$this->master){
     $client=socket_accept($this->master);
     $this->sockets[]=$client;
     $user = array(
      'socket'=>$client,
      'hand'=>false,
     );
     $this->users[] = $user;
     $k=$this->search($client);
     $eventreturn = array('k'=>$k,'sign'=>$sign);
     $this->eventoutput('in',$eventreturn);
    }else{
     $len=socket_recv($sign,$buffer,2048,0);
     $k=$this->search($sign);
     $user=$this->users[$k];
     if($len<7){
      $this->close($sign);
      $eventreturn = array('k'=>$k,'sign'=>$sign);
      $this->eventoutput('out',$eventreturn);
      continue;
     }
     if(!$this->users[$k]['hand']){//没有握手进行握手
      $this->handshake($k,$buffer);
     }else{
      $buffer = $this->uncode($buffer);
      $eventreturn = array('k'=>$k,'sign'=>$sign,'msg'=>$buffer);
      $this->eventoutput('msg',$eventreturn);
     }
    }
   }
  }
 }
 function search($sign){//通过标示遍历获取id
  foreach ($this->users as $k=>$v){
   if($sign==$v['socket'])
   return $k;
  }
  return false;
 }
 function close($sign){//通过标示断开连接
  $k=array_search($sign, $this->sockets);
  socket_close($sign);
  unset($this->sockets[$k]);
  unset($this->users[$k]);
 }
 function handshake($k,$buffer){
  $buf = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18);
  $key = trim(substr($buf,0,strpos($buf,"\r\n")));
  $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
  $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
  $new_message .= "Upgrade: websocket\r\n";
  $new_message .= "Sec-WebSocket-Version: 13\r\n";
  $new_message .= "Connection: Upgrade\r\n";
  $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
  socket_write($this->users[$k]['socket'],$new_message,strlen($new_message));
  $this->users[$k]['hand']=true;
  return true;
 }
 function uncode($str){
  $mask = array();
  $data = '';
  $msg = unpack('H*',$str);
  $head = substr($msg[1],0,2);
  if (hexdec($head{1}) === 8) {
   $data = false;
  }else if (hexdec($head{1}) === 1){
   $mask[] = hexdec(substr($msg[1],4,2));
   $mask[] = hexdec(substr($msg[1],6,2));
   $mask[] = hexdec(substr($msg[1],8,2));
   $mask[] = hexdec(substr($msg[1],10,2));
   $s = 12;
   $e = strlen($msg[1])-2;
   $n = 0;
   for ($i=$s; $i<= $e; $i+= 2) {
    $data .= chr($mask[$n%4]^hexdec(substr($msg[1],$i,2)));
    $n++;
   }
  }
  return $data;
 }
  function code($msg){
   $msg = preg_replace(array('/\r$/','/\n$/','/\r\n$/',), '', $msg);
   $frame = array();
   $frame[0] = '81';
   $len = strlen($msg);
   $frame[1] = $len<16"H*", $data);
  }
  function ord_hex($data) {
   $msg = '';
   $l = strlen($data);
   for ($i= 0; $i<$l; $i++) {
    $msg .= dechex(ord($data{$i}));
   }
   return $msg;
  }
  function idwrite($id,$t){//通过id推送信息
   if(!$this->users[$id]['socket']){return false;}//没有这个标示
   $t=$this->code($t);
   return socket_write($this->users[$id]['socket'],$t,strlen($t));
  }
  function write($k,$t){//通过标示推送信息
   $t=$this->code($t);
   return socket_write($k,$t,strlen($t));
  }
  function eventoutput($type,$event){//事件回调
   call_user_func($this->event,$type,$event);
  }
  function log($t){//控制台输出
   if($this->log){
    $t=$t."\r\n";
    fwrite(STDOUT, iconv('utf-8','gbk//IGNORE',$t));
   }
  }
}

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php socket用法总结》、《php字符串(string)用法总结》、《PHP数学运算技巧总结》、《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP数据结构与算法教程》、《php程序设计算法总结》及《PHP网络编程技巧总结》

希望本文所述对大家PHP程序设计有所帮助。

标签:
PHP,websocket,通信

无为清净楼资源网 Design By www.qnjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
无为清净楼资源网 Design By www.qnjia.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。