作为[PHP] websocket-server,如何在结束帧上设置状态代码?

时间:2015-07-06 19:39:43

标签: php websocket phpwebsocket

关闭控制框看起来像

type:"close"
[payload:""]

所以我们不必发送状态代码和/或(字符串)原因。 但如果我们想 - 怎么样?

我从https://tools.ietf.org/html/rfc6455#section-5.5.1读到 代码和原因属于"应用程序数据" 附加到有效载荷。 因此,在这种情况下,有效负载是应用程序数据。到目前为止一切都很好。

然后它说:

  

如果有一个正文,则前两个字节      主体必须是一个2字节无符号整数(按网络字节顺序)      表示状态代码,其值为/代码/在第7.4节中定义。      在2字节整数之后,主体可以包含UTF-8编码的数据      with value / reason /,其解释未定义      这个规范。   块引用

前两个字节 - 2字节无符号整数 - 好的,例如1001

正文可以包含带有值/原因/ 的UTF-8编码数据 - 确定

但是哪种格式?

 type: close
 payload: 1001shutdown

OO?

我怀疑没有格式。有谁知道怎么样?

= = = = = = = = = = =

修改

感谢Ghedipunk! 这里有一些代码,以防有人想要使用它:

public function encodeClosePayload($code, $reason='')
{
    $code = $this->closeCodeDecToBytes($code);
    return $code . $reason;
}
public function decodeClosePayload($payload)
{
    $code = $this->closeCodeBytesToDec(substr($payload, 0, 2));
    $reason = (strlen($payload) > 2) ? substr($payload, 2) : '';
    return array($code, $reason);
}
protected function closeCodeBytesToDec($bytes)
{
    return hexdec( dechex( ord($bytes[0]) ) . dechex( ord($bytes[1]) ) );
}
protected function closeCodeDecToBytes($dec)
{
    $hex = dechex($dec);
    $second = substr($hex, -2);
    $first = sprintf('%02s', substr($hex, 0, strlen($hex)-strlen($second)));
    return chr('0x' . $first) . chr('0x' . $second);
}

建议欢迎!

1 个答案:

答案 0 :(得分:1)

$payload = "\X03\Xe9Shutdown";

您需要在数字上下文中设置状态,而不是字符串上下文。

将二进制数据注入字符串的最简单方法是将其添加为转义的十六进制数字。

我的计算器告诉我hex 03e9 == dec 1001,但你可以自己确认一下:3 * 256 + 14 * 16 + 9 = 1001。

如果你原样离开它,你的前两个字节将是ascii字符" 10",在数字上下文中是12592.(49 * 256 + 48)

$ php -a
php > $test ="\X03\Xe9Shutdown";
php > var_dump($test);
string(10) "?Shutdown"
php > var_dump(ord($test[0]));
int(3)
php > var_dump(ord($test[1]));
int(233)

如果你发现字符串中的转义十六进制是丑陋的,那么也可以使用PHP pack()函数完成:

$ php -a
php > $test = pack('n*', 1001) . 'Shutdown';
php > var_dump($test);
string(10) "?Shutdown"
php > var_dump(ord($test[0]));
int(3)
php > var_dump(ord($test[1]));
int(233)