Как [PHP] websocket-сервер, как мне установить код состояния в закрывающем кадре?

закрывающий кадр управления выглядит так

type:"close"
[payload:""]

поэтому нам не нужно отправлять код состояния и/или (строку) причину. Но если мы хотим - как?

Я прочитал из https://tools.ietf.org/html/rfc6455#section-5.5.1, что код и причина относятся к «данным приложения», которые добавляются к полезной нагрузке. Таким образом, в этом случае полезной нагрузкой являются данные приложения. Все идет нормально.

Затем он говорит:

Если есть тело, первые два байта тела ДОЛЖНЫ быть 2-байтовым целым числом без знака (в сетевом порядке байтов), представляющим код состояния со значением /code/, определенным в Разделе 7.4. После 2-байтового целого числа тело МОЖЕТ содержать данные в кодировке UTF-8 со значением /reason/, интерпретация которых не определена данной спецификацией. Цитата

первые два байта - 2-байтовое целое число без знака -- OK, например 1001

body МОЖЕТ содержать данные в кодировке UTF-8 со значением /reason/ -- OK

Но какой формат?

 type: close
 payload: 1001shutdown

oO?

Сомневаюсь, что нет формата. Кто-нибудь знает, как?

= = = = = = = = = =

РЕДАКТИРОВАТЬ

спасибо Гедипанку! вот некоторый код на случай, если кто-то захочет его использовать:

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);
}

предложения приветствуются!


person cottton    schedule 06.07.2015    source источник


Ответы (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)
person Ghedipunk    schedule 06.07.2015
comment
$payload = "\X03\Xe9Shutdown"; у меня не сработало. но ord(0x03) . ord(0xe9) . 'shutdown' работает. большое спасибо! изучал это с нескольких недель: D - person cottton; 18.07.2015