php开发websocket服务器,使用 php 连接 websocket 服务器

最近在写一个问卷调查(也可以投票用)系统,因为有一个大屏幕需要实时显示结果,于是用了 websocket。考虑到投票用户用的浏览器可能不支持 websocket,于是就只写了一个普通的表单,向 websocket 传消息的任务就交给了 php。百度了下,找到了个现成的客户端( PHP Websocket 客户端 – 下载频道 – CSDN.NET ),但是下载下来以后试了下发现无法正常使用,于是调整了它的 header,server 端则打印出通讯的 log,结果发现,连接是可以正常建立的,发送数据却失败。查了下资料( 关于websocket – 轩脉刃 – 博客园 ),发现源码中的 senddata 的 function 是错误的,它没有对数据进行处理就直接发送了。发现问题后,我根据通讯协议对源码做了如下修改:

php">

public function sendData($data)

{

// send actual data:

return fwrite($this->_Socket, $this->encode($data)) or die('Error:' . $errno . ':' . $errstr);

$wsData = fread($this->_Socket, 2000);

$retData = trim($wsData,chr(0).chr(255));

return $retData;

}

private function encode( $data ) {

$data = is_array( $data ) || is_object( $data ) ? json_encode( $data ) : (string) $data;

$len = strlen( $data );

$mask=array();

for ($j=0;$j<4;$j++) {

$mask[]=mt_rand(1,255);

}

$head[0] = 129;

if ( $len <= 125 ) {

$head[1] = $len;

} elseif ( $len <= 65535 ) {

$split = str_split( sprintf('%016b', $len ), 8 );

$head[1] = 126;

$head[2] = bindec( $split[0] );

$head[3] = bindec( $split[1] );

} else {

$split = str_split( sprintf('%064b', $len ), 8 );

$head[1] = 127;

for ( $i = 0; $i < 8; $i++ ) {

$head[$i+2] = bindec( $split[$i] );

}

if ( $head[2] > 127 ) {

return false;

}

}

$head[1]+=128;

$head=array_merge($head,$mask);

foreach( $head as $k => $v ) {

$head[$k] = chr( $v );

}

$mask_data='';

for ($j=0;$j

$mask_data.=chr(ord($data[$j]) ^ $mask[$j % 4]);

}

return implode('', $head ) . $mask_data;

}

private function _connect($host, $port)

{

$key1 = $this->_generateRandomString(32);

$key2 = $this->_generateRandomString(32);

$key3 = $this->_generateRandomString(8, false, true);

$header = "GET ws://".$host.":".$port."/ HTTP/1.1\r\n";

$header.= "Host: ".$host.":".$port."\r\n";

$header.= "Connection: Upgrade\r\n";

$header.= "Pragma: no-cache\r\n";

$header.= "Cache-Control: no-cache\r\n";

$header.= "Upgrade: websocket\r\n";

$header.= "Sec-WebSocket-Version: 13\r\n";

$header.= "User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36\r\n";

$header.= "Accept-Encoding: gzip, deflate, sdch\r\n";

$header.= "Accept-Language: zh-CN,zh;q=0.8\r\n";

$header.= "Sec-WebSocket-Key: " . $key1 . "\r\n";

$header.= "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n";

$header.= "\r\n";

$this->_Socket = fsockopen($host, $port, $errno, $errstr, 2);

fwrite($this->_Socket, $header) or die('Error: ' . $errno . ':' . $errstr);

$response = fread($this->_Socket, 2000);

/**

* @todo: check response here. Currently not implemented cause "2 key handshake" is already deprecated.

* See: http://en.wikipedia.org/wiki/WebSocket#WebSocket_Protocol_Handshake

*/

return true;

}

替换源码中的 sendData 与 _connect 并添加 encode function 即可,因为修改之前的源码是别人发布的,所以下载见文章开头的 csdn 链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值