PHP websocket |高频发送数据时出现奇怪字符



我有一个javascript websocket客户端和一个php websocket服务器。当我用循环向服务器发送大量数据时,服务器窗口中出现了奇怪的字符。

我发送

:

setInterval(function() {
    for (var i=1; i<=5; i++) {
        WS.send("0");
    }
}, 1000);

服务器窗口:

Received [1]: 0╩┤&ψ╙]▬)╩Zόrcj
Received [1]: 0
Received [1]: 0≤↓ [☺ψ╧
Received [1]: 0¶╞0UoL
§╧q←%ved [1]: 0Τ
Received [1]: 0b:Ρ"6Τι
Received [1]: 0
Received [1]: 0
Received [1]: 0&Ρ┼→↑αΫ
Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0╦►╬┘Τ7■
Received [1]: 0SΖ╥m╬'έ
Received [1]: 0
Received [1]: 0,!☼┘L╡?
Received [1]: 0L│%☼ΪH§
Received [1]: 0
Received [1]: 0▀μpp┤A@
Received [1]: 0V[A√╚ύq

当我以较低的频率发送数据时,一切正常

我发送

:

setInterval(function() {
    WS.send("0");
}, 1000);

和服务器窗口:

Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0
Received [1]: 0

为什么会发生这种情况?这正常吗?

用于解除数据掩码的函数:

function unmask($data) {
    $length = ord($data[1]) & 127;
    if($length == 126) {$masks = substr($data, 4, 4); $data = substr($data, 8);}
    elseif($length == 127) {$masks = substr($data, 10, 4); $data = substr($data, 14);}
    else {$masks = substr($data, 2, 4); $data = substr($data, 6);}
    $text = "";
    for ($i = 0; $i < strlen($data); ++$i) {$text .= $data[$i] ^ $masks[$i%4];}
    return $text;
}

在这里我收到了消息:

while(socket_recv($client, $buffer, 2048, 0) >= 1) {
    $msg = unmask($buffer);
    echo "$msgn";
}

由于Nagle算法,您在数据包中获得多个WebSocket帧。您发送小消息的速度如此之快,以至于为了最大限度地减少网络拥塞,客户端一直保留数据,直到它得到服务器的确认,或者直到发生合理的超时。

要解决这个问题,您只需要去掉$length字节数,然后在剩余的数据上运行unmask()函数。

你的代码也容易受到超大WebSocket帧在不同数据包中被分割的影响;尝试在消息中发送超过64KB的数据,看看会发生什么。(你可以往下看,看到类似的结果;以太网的MTU是1500字节,但TCP本身的MTU是65536字节,所以当你发送超过64K的数据时,你总是会看到碎片的影响。

在我的服务器中,我为每个连接的用户设置了一个缓冲区,直到我有一个完整的WebSocket帧来处理碎片,并且我一次只从缓冲区的前面取出$header_length + $message_length值的数据,以防缓冲区中有多个帧。

相关内容

  • 没有找到相关文章

最新更新