php PHP中的WebSocket客户端?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7160899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WebSocket client in PHP?
提问by Christian Davén
Is there a library or client for connecting to a WebSocket server from PHP? If not, is there a reason why?
是否有用于从 PHP 连接到 WebSocket 服务器的库或客户端?如果没有,有什么原因吗?
(phpwebsocketonly seem to have Javascript client code.)
(phpwebsocket似乎只有 Javascript 客户端代码。)
回答by Marc Rochkind
None of the above is a good answer. Several of them are about a server, whereas the question is about a client. The code from Rodislav didn't work for me, as it didn't talk to my WebSockets server on Heroku. However, this library worked very well:
以上都不是一个好的答案。其中一些是关于服务器的,而问题是关于客户端的。Rodislav 的代码对我不起作用,因为它没有与 Heroku 上的 WebSockets 服务器通信。但是,这个库运行良好:
https://github.com/Devristo/phpws
https://github.com/Devristo/phpws
UPDATE: While this code worked when all was well, there seems to be no error returns or exceptions at all, and as a result it's unusable when there's an error (e.g., the server isn't running, the address is wrong, the port is blocked, etc.). So, while it was fun to experiment with, it's not usable in production code.
更新:虽然此代码在一切正常时工作,但似乎根本没有错误返回或异常,因此在出现错误时它无法使用(例如,服务器没有运行,地址错误,端口被阻止等)。因此,虽然试验很有趣,但它不能用于生产代码。
回答by Rodislav Moldovan
well, it's easy and you can do in this Thanks to all sources where we found answers (sorry, I can't remember all)
嗯,这很容易,您可以在此完成 感谢我们找到答案的所有来源(抱歉,我不记得全部)
<?php
$host = '10.9.8.173'; //where is the websocket server
$port = 8575;
$local = "http://mypc"; //url where this script run
$data = "first message"; //data to be send
$head = "GET / HTTP/1.1"."\r\n".
"Upgrade: WebSocket"."\r\n".
"Connection: Upgrade"."\r\n".
"Origin: $local"."\r\n".
"Host: $host"."\r\n".
"Sec-WebSocket-Key: asdasdaas76da7sd6asd6as7d"."\r\n".
"Content-Length: ".strlen($data)."\r\n"."\r\n";
//WebSocket handshake
$sock = fsockopen($host, $port, $errno, $errstr, 2);
fwrite($sock, $head ) or die('error:'.$errno.':'.$errstr);
$headers = fread($sock, 2000);
echo $headers;
fwrite($sock, hybi10Encode($data)) or die('error:'.$errno.':'.$errstr);
$wsdata = fread($sock, 2000);
var_dump(hybi10Decode($wsdata));
fclose($sock);
function hybi10Decode($data)
{
$bytes = $data;
$dataLength = '';
$mask = '';
$coded_data = '';
$decodedData = '';
$secondByte = sprintf('%08b', ord($bytes[1]));
$masked = ($secondByte[0] == '1') ? true : false;
$dataLength = ($masked === true) ? ord($bytes[1]) & 127 : ord($bytes[1]);
if($masked === true)
{
if($dataLength === 126)
{
$mask = substr($bytes, 4, 4);
$coded_data = substr($bytes, 8);
}
elseif($dataLength === 127)
{
$mask = substr($bytes, 10, 4);
$coded_data = substr($bytes, 14);
}
else
{
$mask = substr($bytes, 2, 4);
$coded_data = substr($bytes, 6);
}
for($i = 0; $i < strlen($coded_data); $i++)
{
$decodedData .= $coded_data[$i] ^ $mask[$i % 4];
}
}
else
{
if($dataLength === 126)
{
$decodedData = substr($bytes, 4);
}
elseif($dataLength === 127)
{
$decodedData = substr($bytes, 10);
}
else
{
$decodedData = substr($bytes, 2);
}
}
return $decodedData;
}
function hybi10Encode($payload, $type = 'text', $masked = true) {
$frameHead = array();
$frame = '';
$payloadLength = strlen($payload);
switch ($type) {
case 'text':
// first byte indicates FIN, Text-Frame (10000001):
$frameHead[0] = 129;
break;
case 'close':
// first byte indicates FIN, Close Frame(10001000):
$frameHead[0] = 136;
break;
case 'ping':
// first byte indicates FIN, Ping frame (10001001):
$frameHead[0] = 137;
break;
case 'pong':
// first byte indicates FIN, Pong frame (10001010):
$frameHead[0] = 138;
break;
}
// set mask and payload length (using 1, 3 or 9 bytes)
if ($payloadLength > 65535) {
$payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8);
$frameHead[1] = ($masked === true) ? 255 : 127;
for ($i = 0; $i < 8; $i++) {
$frameHead[$i + 2] = bindec($payloadLengthBin[$i]);
}
// most significant bit MUST be 0 (close connection if frame too big)
if ($frameHead[2] > 127) {
$this->close(1004);
return false;
}
} elseif ($payloadLength > 125) {
$payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8);
$frameHead[1] = ($masked === true) ? 254 : 126;
$frameHead[2] = bindec($payloadLengthBin[0]);
$frameHead[3] = bindec($payloadLengthBin[1]);
} else {
$frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;
}
// convert frame-head to string:
foreach (array_keys($frameHead) as $i) {
$frameHead[$i] = chr($frameHead[$i]);
}
if ($masked === true) {
// generate a random mask:
$mask = array();
for ($i = 0; $i < 4; $i++) {
$mask[$i] = chr(rand(0, 255));
}
$frameHead = array_merge($frameHead, $mask);
}
$frame = implode('', $frameHead);
// append payload to frame:
for ($i = 0; $i < $payloadLength; $i++) {
$frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
}
return $frame;
}
?>
回答by fiddur
I tried to use many of the above to include in tivoka (json-rpc), but they either wasn't good enough reading larger packets (not getting the whole frame or reading into the next one) or had large dependencies.
我尝试使用上述许多内容包含在 tivoka (json-rpc) 中,但它们要么不足以读取较大的数据包(未获取整个帧或读取下一个数据包),要么具有很大的依赖性。
So, I wrote https://github.com/Textalk/websocket-php
所以,我写了https://github.com/Textalk/websocket-php
Instead of first reading all available data from the socket and then decoding it, it reads the frame header and parses payload length, and then loads just that.
它不是首先从套接字读取所有可用数据然后对其进行解码,而是读取帧头并解析有效负载长度,然后仅加载该数据。
It lacks ping/pong support, but I think it does most of the other stuff well. It works well with tivoka and is at least 92% autotested :) It might need some extra functions to check if there is another frame without actually reading it.
它缺乏乒乓/乒乓支持,但我认为它可以很好地完成其他大部分工作。它适用于 tivoka,并且至少 92% 是自动测试的 :) 它可能需要一些额外的功能来检查是否有另一个框架而不实际读取它。
Let me know what you think.
让我知道你的想法。
回答by singpolyma
This library looks pretty good, if you're ok with the dependencies: https://github.com/gabrielbull/php-websocket-client
这个库看起来不错,如果你对依赖项没问题:https: //github.com/gabrielbull/php-websocket-client
回答by Jithin Jose
A PHP Websocket library with an example chat application. With demo and full description of implementation.
带有示例聊天应用程序的 PHP Websocket 库。带有演示和实现的完整描述。
http://www.techzonemind.com/php-websocket-library-two-way-real-time-communication/
http://www.techzonemind.com/php-websocket-library-two-way-real-time-communication/