Решение этой проблемы заключается в следующем
Выпуск: При получении длинных байт данных с помощью WebSocket с чем-то вроде socket_recv($socket,$buffer,5000,0);
вы не можете получить полные данные в одном вызове и вам нужно вызвать socket_recv($socket,$buffer,5000,0);
снова.
Например, предположим, что мы отправили 8000 байт данных из браузера в websocket с помощью JS (socket.send). На стороне сервера мы будем использовать socket_recv для получения сообщения. Но мы можем получить только около 4000 байт данных и, возможно, придется снова вызвать socket_recv, чтобы получить оставшиеся 4000 байт.
Теперь в моем исходном коде я использовал функцию «unmask» сразу после вызова socket_recv, чтобы разобрать данные. Это будет работать для первого набора полученных сообщений. Но для следующего набора сообщений функция «unmask» попытается извлечь новую маску и применить ее. Это была ошибка, так как сообщение является продолжением предыдущего сообщения, а Mask не изменяется. Решение состоит в том, чтобы сохранить маску от первого сообщения и проверить, является ли следующее сообщение продолжением или нет. Это можно сделать, проверив первый бит сообщения.
$fin=ord($payload[0]) & 0x77;
если $ fin - это сообщение, это новое сообщение, если оно не является продолжением предыдущего сообщения. В случае ($ fin! = 1) вам нужно использовать маску вашего предыдущего сообщения, чтобы разоблачить сообщение. Не забывайте, так как вам нужно снова использовать значение маски, вам нужно определить его вне функции и сделать его глобальным.
Я предоставил старый и новый код ниже для справки. Надеюсь, это правильное решение, но, пожалуйста, не стесняйтесь добавлять что-либо или сообщать мне, если я ошибаюсь.
Мой Оригинальная функция Унмаск:
function unmask($payload) {
$length = ord($payload[1]) & 127;
if($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
$firstcode=substr($payload, 1, 1);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
$firstcode=substr($payload, 1, 1);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
$firstcode=substr($payload, 1, 1);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i]^$masks[$i%4];
}
return $text;
}
Обновлено Функция:
function unmask($payload,$masks) {
global $masks;
$fin=ord($payload[0]) & 0x77;
if($fin!=1){
$data=substr($payload,0);
$text='';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i]^$masks[$i%4];
}
return $text;
}else{
$length = ord($payload[1]) & 127;
Echo "Mask functiion Payload Lenght".$length."\n";
if($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i]^$masks[$i%4];
}
return $text;
}
}
Sockets = WebSockets –
Благодаря код ошибки 0, но я полагал, что я не получаю неполных данных но данные фрагментированы. Теперь я действительно зациклился на том, как разоблачить фрагментированные данные. Я могу получить первый снимок, но не смог замаскировать следующий кадр. – user2288650