php socket 协议,php WebSocket 新旧协议收发数据的问题

class WebSocket{

var $master;

var $sockets = array();

var $users = array();

var $debug = false;

function __construct($address,$port){

error_reporting(E_ALL);

set_time_limit(0);

ob_implicit_flush();

$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,20) or die("socket_listen() failed");

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

$this->say("Server Started : ".date('Y-m-d H:i:s'));

$this->say("Listening on : ".$address." port ".$port);

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

while(true){

$changed = $this->sockets;

$write=NULL;

$except=NULL;

socket_select($changed,$write,$except,NULL);

foreach($changed as $socket){

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

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

if($client<0){ $this->say("socket_accept() failed"); continue; }

else{ $this->connect($client); }

}

else{

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

if($bytes==0){ $this->disconnect($socket); }

else{

$this->say('Their Words: '.$buffer);

$user = $this->getuserbysocket($socket);

if(!$user->handshake){ $this->dohandshake($user,$buffer); }

else{ $this->process($user,$this->unwrap($buffer)); }

}

}

}

}

}

function process($user,$msg){

/* Extend and modify this method to suit your needs */

/* Basic usage is to echo incoming messages back to client */

$this->send($user->socket,$msg);

}

function send($client,$msg){

$this->say("> ".$msg);

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

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

$this->say("! ".strlen($msg));

}

function connect($socket){

$user = new User();

$user->id = uniqid();

$user->socket = $socket;

array_push($this->users,$user);

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

$this->say($socket." CONNECTED!");

$this->say(date("d/n/Y ")."at ".date("H:i:s T"));

}

function disconnect($socket){

$found=null;

$n=count($this->users);

for($i=0;$i

if($this->users[$i]->socket==$socket){ $found=$i; break; }

}

if(!is_null($found)){ array_splice($this->users,$found,1); }

$index=array_search($socket,$this->sockets);

socket_close($socket);

$this->say($socket." DISCONNECTED!");

if($index>=0){ array_splice($this->sockets,$index,1); }

}

/*Old way:

function dohandshake($user,$buffer){

$this->say("\nRequesting handshake...");

$this->say($buffer);

list($resource,$host,$origin,$key1,$key2,$l8b) = $this->getheaders($buffer);

$this->say("Handshaking...");

//$port = explode(":",$host);

//$port = $port[1];

//$this->say($origin."\r\n".$host);

$upgrade = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" .

"Upgrade: WebSocket\r\n" .

"Connection: Upgrade\r\n" .

"Sec-WebSocket-Origin: " . $origin . "\r\n" .

"Sec-WebSocket-Location: ws://" . $host . $resource . "\r\n" .

"\r\n" .

$this->calcKey($key1,$key2,$l8b) . "\r\n";// .

//"\r\n";

socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0)));

$user->handshake=true;

$this->say($upgrade);

$this->say("Done handshaking...");

return true;

}*/

function dohandshake($user,$buffer){

$this->say("\nStart ShakeHanding\nFollowing is from client\n");

$this->say($buffer);

$this->say("\nFollowing is ours\n");

if(preg_match("/Sec-WebSocket-Key1/",$buffer)){

list($resource,$host,$origin,$key1,$key2,$l8b) = $this->getheaders($buffer);

$upgrade = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" .

"Upgrade: WebSocket\r\n" .

"Connection: Upgrade\r\n" .

"Sec-WebSocket-Origin: " . $origin . "\r\n" .

"Sec-WebSocket-Location: ws://" . $host . $resource . "\r\n" .

"\r\n" .$this->calcKey($key1,$key2,$l8b) . "\r\n";

}

elseif(preg_match("/Sec-WebSocket-Key:/",$buffer)){

preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$buffer,$match);

$key=$match[1];

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

$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";

}

$this->say($upgrade);

socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0)));

$user->handshake=true;

$this->say("Finish ShakeHanding.");

return true;

}

function calcKey($key1,$key2,$l8b){

//Get the numbers

preg_match_all('/([/d]+)/', $key1, $key1_num);

preg_match_all('/([/d]+)/', $key2, $key2_num);

//Number crunching [/bad pun]

$this->say("Key1: " . $key1_num = implode($key1_num[0]) );

$this->say("Key2: " . $key2_num = implode($key2_num[0]) );

//Count spaces

preg_match_all('/([ ]+)/', $key1, $key1_spc);

preg_match_all('/([ ]+)/', $key2, $key2_spc);

//How many spaces did it find?

$this->say("Key1 Spaces: " . $key1_spc = strlen(implode($key1_spc[0])) );

$this->say("Key2 Spaces: " . $key2_spc = strlen(implode($key2_spc[0])) );

if($key1_spc==0|$key2_spc==0){ $this->say("Invalid key");return; }

//Some math

$key1_sec = pack("N",$key1_num / $key1_spc); //Get the 32bit secret key, minus the other thing

$key2_sec = pack("N",$key2_num / $key2_spc);

//This needs checking, I'm not completely sure it should be a binary string

return md5($key1_sec.$key2_sec.$l8b,1); //The result, I think

}

function getheaders($req){

$r=$h=$o=null;

if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; }

if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; }

if(preg_match("/Origin: (.*)\r\n/" ,$req,$match)){ $o=$match[1]; }

if(preg_match("/Sec-WebSocket-Key1: (.*)\r\n/",$req,$match)){ $this->say("Sec Key1: ".$sk1=$match[1]); }

if(preg_match("/Sec-WebSocket-Key2: (.*)\r\n/",$req,$match)){ $this->say("Sec Key2: ".$sk2=$match[1]); }

if($match=substr($req,-8)) { $this->say("Last 8 bytes: ".$l8b=$match); }

return array($r,$h,$o,$sk1,$sk2,$l8b);

}

function getuserbysocket($socket){

$found=null;

foreach($this->users as $user){

if($user->socket==$socket){ $found=$user; break; }

}

return $found;

}

function say($msg=""){ echo $msg."\n"; }

function wrap($msg=""){ return chr(0).$msg.chr(255); }

function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); }

}

class User{

var $id;

var $socket;

var $handshake;

}

(请格式化上面的代码)

以上的代码源自http://blog.csdn.net/trace332/article/details/6325986

不过很明显,CSDN的那位楼主有许多语法错误,还有WebSocket的协议版本低。

我修改后新旧协议都能正常实现握手,不过关于收发数据还是无从下手,恳请大虾们赐教一二.

(新协议收发的是二进制数据,详细的另见其他文献)

(我只想收发UTF-8字符)

(请也做到新旧都能兼容)

(谢谢!)

  • 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、付费专栏及课程。

余额充值