workerman对不间断TCP数据流的高效处理

daling

一个客户端通过Socket tcp协议连接到workerman后,源源不断的向服务器传输数据,数据用#号标识该条数据开始,用-号分割数据项,用!号标识该条数据结束。没有包边界,因为数据较小,每次接受到很多条数据,通过onMessage打印出来看,如下,怎么才能将每条数据的第三列取出来,并且不丢数据呢?

数据样列:

#558-A365485-954569-854121!
#558-B785485-521459--!
#558-A856915-556214-854121!
#558-A320015-777510--!
#558-A032154-002541-854121!
#558-A666214-669555-854121!
#558-A985115-222010--!
#558-A344512-663254-854121!
………………

每次触发onMessage的时候可以echo到接受的数据条数不一样,但是格式都如上,怎样可以高效的将每条数据第三项数字取出来,最好能存变量,广播给用户组。

// 远程websocket服务器发来消息时
$ws_connection->onMessage = function($connection, $data){
    //echo "recv: $data\n";
    这里怎样写高效的处理代码??
};
5981 4 1
4个回答

daling

558前面都有#号,被问答转义了,数据样例如下

#558-A365485-954569-854121!
#558-B785485-521459--!
#558-A856915-556214-854121!
#558-A320015-777510--!
#558-A032154-002541-854121!
#558-A666214-669555-854121!
#558-A985115-222010--!
#558-A344512-663254-854121!

  • 暂无评论
walkor

要写一个通讯协议来分包,看下手册通讯协议部分。分包可以保证每次onMesage的数据是完整的,并且不会因为粘包导致数据丢失。
http://doc3.workerman.net/protocols/how-protocols.html

  • 暂无评论
daling

好的,谢谢,原来要自定义协议粘包。
还有一个,workerman中可接收的缓冲大小是否由TcpConnection::$maxSendBufferSize决定,假设因为onMesage的回调函数不能及时处理接收的数据流,导致$maxSendBufferSize占满,客户端是否在$maxSendBufferSize腾空前不能传输数据流。

  • 暂无评论
walkor

maxSendBufferSize 是发送缓冲区的大小,当服务端发送速度大于客户端接收速度时,数据会挤压在发送缓冲区,如果发送缓冲区满,则触发onBufferFull事件回调,在这个事件回调中做处理(例如停止向客户端继续发送数据)。

如果onMesage不能及时处理数据,数据会首先数据会积压在客户端socket发送缓冲区(操作系统提供,大小约几十K)和workerman服务器的socket接受缓冲区(操作系统提供,大小约几十K),如果客户端socket发送缓冲区满,则客户端调用socket写操作将阻塞(block模式)或者立刻返回失败(非阻塞模式),当服务端onMessage处理完毕再次读取本地socket接收缓冲区数据后,客户端socket发送缓冲区的数据会继续发送过来到服务端socket接收缓冲区,然后依次循环。

所以当服务端onMessage不能及时处理数据,不会导致maxSendBufferSize满,但是可能会导致数据在客户端和服务端的socket缓冲区积压。

  • 暂无评论
年代过于久远,无法发表回答
🔝