class WebsocketClient
{
private $_Socket = null;
public function __construct($host, $port)
{
$this->_connect($host, $port);
}
public function __destruct()
{
$this->_disconnect();
}
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 < $len; $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;
}
private function _disconnect()
{
fclose($this->_Socket);
}
private function _generateRandomString($length = 10, $addSpaces = true, $addNumbers = true)
{
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"§$%&/()=[]{}';
$useChars = array();
// select some random chars:
for ($i = 0; $i < $length; $i ++)
{
$useChars[] = $characters[mt_rand(0, strlen($characters) - 1)];
}
// add spaces and numbers:
if ($addSpaces === true)
{
array_push($useChars, ' ', ' ', ' ', ' ', ' ', ' ');
}
if ($addNumbers === true)
{
array_push($useChars, rand(0, 9), rand(0, 9), rand(0, 9));
}
shuffle($useChars);
$randomString = trim(implode('', $useChars));
$randomString = substr($randomString, 0, $length);
return $randomString;
}
}
能向服务器发送数组,怎么接收数据?