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

时间:2015-09-07 22:10:13

标签: php websocket character

我有一个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 "$msg\n";
}

1 个答案:

答案 0 :(得分:2)

由于Nagle's Algorithm,您的数据包中会出现多个WebSocket帧。您发送小消息的速度非常快,以便最大限度地减少网络拥塞,客户端会保留数据,直到从服务器获得确认,或者直到发生合理的超时为止。

要解决此问题,您只需关闭$length个字节数,然后对剩余数据运行unmask()函数。

您的代码也容易受到超大WebSocket帧在不同数据包之间分配的影响;尝试在邮件中发送超过64KB的数据,看看会发生什么。 (您可以降低并看到类似的结果;以太网的MTU为1500字节,但TCP本身的MTU为65536字节,因此当您发送超过64K时,您将始终看到碎片的影响。)

在我的服务器中,我为每个连接的用户提供了一个缓冲区,直到我有一个完整的WebSocket框架来处理碎片,我只从该缓冲区的前面拉出$header_length + $message_length个值的数据一次,如果该缓冲区中有多个帧。