socket.io发出数据将断开客户端

时间:2013-03-14 21:18:51

标签: node.js socket.io

我正在聊天,我注意到有时我的node.js服务器和iOS客户端之间的连接会在服务器发出一些数据后立即断开连接。

我连续发出两个事件,根据客户端上的日志,看来发出的数据是“合并”的:

doQueue() >> 0
2013-03-16 05:11:45.390 [833:907] start/reset timeout
2013-03-16 05:11:45.491 [833:907] onData �187�5:::{"name":"threadInformation","args":[{"threadObjects":[{"threadId":"heacrsi1","users":[{"userName":"tester","userId":"123"},{"userName":"Name","userId":"123"}]}]}]}�171�5:::{"name":"message","args":[{"fromUserName":"tester","fromUserId":"123","text":"heiiiii this is going to trigger a message for u!","threadId":"heacrsi1","messageId":1}]}
2013-03-16 05:11:45.493 [833:907] start/reset timeout
2013-03-16 05:11:45.495 [833:907] disconnect
2013-03-16 05:11:45.496 [833:907] onDisconnect()

我可以一致地重现这个问题。数据“合并”是正常的吗?为什么会发生断线?

编辑:我设法将我的问题简化为非常简单的事情:

这段代码没问题:

    socket.on('online', function(data){
        socket.emit("message", {"testField":"testData2"});
    });

这段代码断开了客户端!:

    socket.on('online', function(data){
        socket.emit("message", {"testField":"testData"});
        socket.emit("message", {"testField":"testData2"});
    });

我们是否不允许连续向插座发射物品?我是否应该自己实现某种队列以确保在发出下一个数据之前每个socket.emit都成功了?

=====更新=====

p / s 1:这只发生在objective-c客户端上。如果我使用javascript客户端,我可以收到这两个事件。

p / s 2:我设法通过一个非常简单的设置重现了这个问题: 一个。首先,服务器在建立连接时只发出两个事件:     io.sockets.on('connection',function(socket)     {         socket.emit(“message”,{“text”:“welcome2!”});         socket.emit(“message”,{“text”:“welcome3!”});     } 湾第二,一个简单的iOS客户端(使用来自这里的socket.IO-obj库:https://github.com/pkyeck/socket.IO-objc

- (void) viewDidLoad
{
    [super viewDidLoad];
    socketIO = [[SocketIO alloc] initWithDelegate:self];
    [socketIO connectToHost:@"192.168.1.87" onPort:5000 withParams:@{@"token":@"avalidtoken"}];
}

℃。 iOS客户端的输出:

    2013-03-21 01:13:39.355 SocketTesterARC[6391:907] Connecting to socket with URL:         http://192.168.1.87:5000/socket.io/1/?t=16807&token=avalidtoken
    2013-03-21 01:13:39.620 SocketTesterARC[6391:907] didReceiveResponse() 200
    2013-03-21 01:13:39.621 SocketTesterARC[6391:907] connectionDidFinishLoading()         fvSZFJMiIXop5uMayU0t:60:60:xhr-polling
    2013-03-21 01:13:39.622 SocketTesterARC[6391:907] sid: fvSZFJMiIXop5uMayU0t
    2013-03-21 01:13:39.656 SocketTesterARC[6391:907] heartbeatTimeout: 67.000000
    2013-03-21 01:13:39.657 SocketTesterARC[6391:907] transports: (
        "xhr-polling"
    )
    2013-03-21 01:13:39.658 SocketTesterARC[6391:907] xhr polling supported -> using it         now
    2013-03-21 01:13:39.680 SocketTesterARC[6391:907] onData 1::
    2013-03-21 01:13:39.681 SocketTesterARC[6391:907] start/reset timeout
    2013-03-21 01:13:39.683 SocketTesterARC[6391:907] connected
    2013-03-21 01:13:39.684 SocketTesterARC[6391:907] onConnect()
    2013-03-21 01:13:39.685 SocketTesterARC[6391:907] connected to server successfully
    2013-03-21 01:13:39.686 SocketTesterARC[6391:907] doQueue() >> 0
    2013-03-21 01:13:39.687 SocketTesterARC[6391:907] start/reset timeout
    2013-03-21 01:13:39.698 SocketTesterARC[6391:907] onData �52�5:::{"name":"message","args":[{"text":"welcome2!"}]}�52�5:::{"name":"message","args":[{"text":"welcome3!"}]}
    2013-03-21 01:13:39.700 SocketTesterARC[6391:907] start/reset timeout
    2013-03-21 01:13:39.701 SocketTesterARC[6391:907] disconnect
    2013-03-21 01:13:39.702 SocketTesterARC[6391:907] onDisconnect()
    2013-03-21 01:13:39.708 SocketTesterARC[6391:907] disconnected! error: Error Domain=SocketIOError Code=-2 "The operation couldn’t be completed. (SocketIOError error -2.)"
    2013-03-21 01:13:44.687 SocketTesterARC[6391:907] disconnect!

1 个答案:

答案 0 :(得分:2)

经过一番挖掘,看来问题已经归结为socket.io将多条消息组合成一个数据包。

两个问题(#65 #83)描述了手头的问题,并进一步详细讨论了该问题。

总之,socket.IO-objc库没有处理这些特殊情况,并且总是假设数据包只包含一条消息。

问题#65供参考:

  

每隔一段时间(在繁重的套接字流量期间),服务器就可以   决定发送一个有效载荷,其中多个数据包在a中返回   单轮询响应(例如,如果使用xhr-polling)。他们是   由\ ufffd字符分隔,并包含每个字节的长度   数据包,如:

�[packet_0 length]�[packet_0]�[packet_1 length]�[packet_1]�[packet_n
     

长度] [packet_n]

     

目前,我相信onData只处理数据   作为单个数据包,但有时服务器发送多个   单个响应中的数据包。

注意 是\ufffd字符。

早些时候fix has been submitted,并且看起来正在审核中。