php解析websocket包,Minicap数据解析(PHP-Websocket)

namespace console\controllers;

use yii\console\Controller;

use console\controllers\MiniStream;

/**

* Description of websocketController

*

* @author fengbo

*/

class WebsocketController extends Controller

{

public function actionIndex()

{

$ws = new WS("127.0.0.1",2000);

}

}

class WS {

var $master; // 连接 server 的 client

var $sockets = array(); // 不同状态的 socket 管理

var $handshake = false; // 判断是否握手

function __construct($address, $port){

// 建立一个 socket 套接字

$this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)

or die("socket_create() failed");

socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1)

or die("socket_option() failed");

socket_bind($this->master, $address, $port)

or die("socket_bind() failed");

socket_listen($this->master, 2)

or die("socket_listen() failed");

$this->sockets[] = $this->master;

// debug

echo("Master socket : ".$this->master."\n");

while(true) {

//自动选择来消息的 socket 如果是握手 自动选择主机

$write = NULL;

$except = NULL;

socket_select($this->sockets, $write, $except, NULL);

foreach ($this->sockets as $socket) {

//连接主机的 client

if ($socket == $this->master){

$client = socket_accept($this->master);

if ($client < 0) {

// debug

echo "socket_accept() failed";

continue;

} else {

//connect($client);

array_push($this->sockets, $client);

echo "connect client\n";

}

} else {

$bytes = @socket_recv($socket,$buffer,2048,0);

print_r($buffer);

if($bytes == 0) return;

if (!$this->handshake) {

// 如果没有握手,先握手回应

$this->doHandShake($socket, $buffer);

echo "shakeHands\n";

} else {

// 如果已经握手,直接接受数据,并处理

$buffer = $this->decode($buffer);

//process($socket, $buffer);

echo "**********************************start************************************\n";

$mini = new MiniStream($client);

$mini->socket();

echo '************************************end************************************';

}

}

}

}

}

function dohandshake($socket, $req)

{

// 获取加密key

$acceptKey = $this->encry($req);

$upgrade = "HTTP/1.1 101 Switching Protocols\r\n" .

"Upgrade: websocket\r\n" .

"Connection: Upgrade\r\n" .

"Sec-WebSocket-Accept: " . $acceptKey . "\r\n" .

"\r\n";

echo "dohandshake ".$upgrade;

// 写入socket

socket_write($socket,$upgrade, strlen($upgrade));

// 标记握手已经成功,下次接受数据采用数据帧格式

$this->handshake = true;

}

function encry($req)

{

$key = $this->getKey($req);

$mask = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

return base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));

}

function getKey($req)

{

$key = null;

if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $req, $match)) {

$key = $match[1];

}

return $key;

}

// 解析数据帧

function decode($buffer)

{

$len = $masks = $data = $decoded = null;

$len = ord($buffer[1]) & 127;

if ($len === 126) {

$masks = substr($buffer, 4, 4);

$data = substr($buffer, 8);

} else if ($len === 127) {

$masks = substr($buffer, 10, 4);

$data = substr($buffer, 14);

} else {

$masks = substr($buffer, 2, 4);

$data = substr($buffer, 6);

}

for ($index = 0; $index < strlen($data); $index++) {

$decoded .= $data[$index] ^ $masks[$index % 4];

}

return $decoded;

}

// 返回帧信息处理

function frame($s)

{

$a = str_split($s, 125);

if (count($a) == 1) {

return "\x81" . chr(strlen($a[0])) . $a[0];

}

$ns = "";

foreach ($a as $o) {

$ns .= "\x81" . chr(strlen($o)) . $o;

}

return $ns;

}

// 返回数据

function send($client, $msg)

{

$msg = $this->frame($msg);

socket_write($client, $msg, strlen($msg));

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现基于Websocket 协议的 PHP类库 和 javascript类库 , 实现事件 回调函数的架构开发,以一个简单聊天室实例介绍其使用方法: 不同浏览器,不同电脑,不同地域, 实时通讯。实现的详细 请研究源码。 /***服务端****/ /**  * 实例化  */ $io = new SocketIO('127.0.0.1',8000); /**  * 监听连接  */ $io->on('connect',function($ws,$uid){ $msg = "任意数据类型,结构需要和前端协议,便于通信";     $ws->broadcast(evet, $msg);     //$ws->emit(evet, $uid, $msg); }); /**  * 任意事件,与前端协议好,// evet 由开发者定义  */ $io->on('event',function($ws,$uid,$msg){     $msg = "任意数据类型,结构需要和前端协议,便于通信";     $ws->broadcast(evet, $msg); }); /* * 关闭 */ $io->on('close',function($ws,$uid,$err){     // evet 由开发者定义     $msg = "任意数据类型,结构需要和前端协议,便于通信";     $ws->broadcast('close', $msg); }); /**  * 启动  */ $io->run();   /*** 客户端 ***/ var io = new SocketIO('127.0.0.1',8000); io.on('connect',function(){      console.log('open');      // 发出请求, event 由开发者定义      io.emit(event, user, function(ok){           if(ok){                        }else{                           }      });      // 收到消息, event 由开发者定义      io.on(event, function(msg){                        console.log(msg);      });      //关闭事件  io.on('close', function(){ }); }); 标签:phpws
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值