socket.io发送数据将导致客户端断开连接

4

我正在开发一个聊天应用,有时候我发现我的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 在发出下一个数据之前都是成功的?
===== 更新 =====
附言1:这只发生在 Objective-C 客户端上。如果我使用 JavaScript 客户端,则可以接收到这两个事件。
附言2:我设法在一个非常简单的设置中重现了问题: a. 首先,一个服务器,在连接建立时简单地发出两个事件: io.sockets.on('connection', function(socket) { socket.emit("message", {"text":"welcome2!"}); socket.emit("message", {"text":"welcome3!"}); } b. 其次,一个简单的 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"}];
}

c. 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 �525:::{"name":"message","args":[{"text":"welcome2!"}]}�525:::{"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!

你的字符串中有任何错误数据吗? - kobe
不,它们是普通数据。 - mkto
这只发生在iOS客户端上吗?如果是,你使用的是哪个库? - travis
1
只出现在iOS上。使用socket.IO-objc库。我已经更新了我的问题。 - mkto
请查看以下问题:https://github.com/pkyeck/socket.IO-objc/issues/65可能是因为您正在使用xhr轮询,所以这可能是您的问题。看起来已经提交了一个修复程序,但可能需要一段时间才能被接受,您可以在此处查看:https://github.com/pkyeck/socket.IO-objc/pull/86 - travis
显示剩余4条评论
1个回答

2
经过一番搜索,似乎问题出在socket.io如何将多个消息组合成单个数据包上。
两个问题(#65 #83)描述了当前的问题,并详细讨论了该问题。
总之,socket.IO-objc库没有处理这些特殊情况,并始终假定一个数据包只包含单个消息。
参考问题#65:

Every once in a while (during heavy socket traffic), the server can decide to send a payload where multiple packets are returned in a single poll response (if using xhr-polling, for example). They are separated by the \ufffd character, and include the byte length of each packet, like:

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

length]�[packet_n]

Currently, I believe onData merely handles the data as a single packet, but there are cases when the server sends multiple packets in a single response.

注意:�是字符\ufffd

早先已经提交了修复请求,根据此次发布的信息看来正在审核中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接