2017-01-21 45 views
0

我有以下代码接收数据与websocket。PHP Websocket接收不完整的数据

$bytes=socket_recv($socket,$buffer2,1024,0); 
$datarec=unmask($buffer2); 
//process further 

这可行,但很多时候我收到不完整的消息,我无法进一步处理数据。

我想出了以下解决方案。

基本上我保留了数据长度的前10位数字,并在使用socket.send从javascript发送数据之前,我在消息开始处添加了数据长度。因此,如果我的信息是“你好,这是一条消息”,它会变成“30:sizehello这是一条消息”我补偿了添加的“30:尺寸”。

在PHP端我希望能够做到这一点

首先读取10位。

$length=socket_recv($socket,$buffer2,1024,MSG_WAITALL); 

,然后使用类似

$datarec=aocket_recv($socket,$buffer2,$length,MSG_WAITALL); 

可悲的是,因为我无法读取和揭露与socket_recv第二次接收到的数据,这并不工作。

有关如何确保从WebSocket获取完整数据而不必事先知道数据长度的任何建议。谢谢你的帮助。

+0

套接字=的WebSockets –

+0

由于错误代码为0,但我想我没有得到完整的数据但数据是分散的。现在,我真的被困在如何揭露碎片数据。我可以取消第一帧,但无法屏蔽下一帧。 – user2288650

回答

0

解决这个问题如下

问题:当接收使用的WebSocket的东西,如socket_recv($socket,$buffer,5000,0);你可能不会得到在一次调用完整的数据资料的长字节,则需要再次调用socket_recv($socket,$buffer,5000,0);

例如,假设我们用JS(socket.send)从浏览器向websocket发送了8000字节的数据。在服务器端,我们将使用socket_recv来获取消息。但是,我们可能只会首先收到大约4000个字节的数据,并且可能需要再次调用socket_recv才能获得剩余的4000个字节。

现在在我的原始代码中,我曾经调用socket_recv来取消屏蔽数据后,调用函数“unmask”。这将适用于收到的第一组消息。但对于下一组消息,“解除掩码”功能将尝试提取新的掩码并应用该掩码。这是错误,因为消息是以前消息的延续,并且Mask不会更改。解决方案是保持第一条消息的掩码,并检查下一条消息是否继续。这可以通过检查消息的第一位来完成。

$fin=ord($payload[0]) & 0x77; 

如果$翅片1的消息是一个新的消息,如果不是它是前一消息的延续。在($ fin!= 1)的情况下,您需要使用之前消息的掩码来揭露消息。不要忘记,因为您需要再次使用mask的值,您需要在函数外部定义它并使其成为全局的。

我已经提供了以下新旧代码供您参考。我希望这是正确的解决方案,但请随时添加任何内容或让我知道我是否在任何地方出错。

我原来的取消屏蔽功能:

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

}