发出数据会断开客户端

发出数据会断开客户端

本文介绍了socket.io 发出数据会断开客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a chat and I noticed that sometimes connection between my node.js server and iOS client will be disconnected right after server emitted some data.

我连续发出两个事件,根据客户端上的日志,发出的数据似乎是组合"的:

I emited two events continuously, based on the logs on the client, it appears that the emitted data are "combined":

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()

我可以始终如一地重现这个问题.数据合并"是否正常?为什么会出现这种断开连接?

I can reproduce this problem consistently. Is it normal that the data is "combined"? Why is this disconnection happening?

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

I managed to simplify my issues into something really simple:

这段代码没问题:

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

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

This piece of code disconnects the client!:

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

我们是否不允许连续向套接字发送某些内容?我是否应该自己实现某种队列以确保在我发出下一个数据之前每个 socket.emit 都成功?

Are we not allowed to emit something to a socket continuously? Am I supposed to implement some sort of queue myself to ensure every socket.emit is successful before i emit the next data?

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

===== UPDATE =====

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

p/s 1: This only happens on objective-c client. If I use a javascript client, I can receive the two events.

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)

p/s 2: I managed to reproduce the problem in a very simple setup:a. First, a server that simply emits two events when a connection is made: io.sockets.on('connection', function(socket) { socket.emit("message", {"text":"welcome2!"}); socket.emit("message", {"text":"welcome3!"}); }b. Second, a simple iOS client (using socket.IO-obj library from here: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 客户端的输出:

c. output from iOS client:

    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!

推荐答案

经过一番挖掘,似乎问题归结为 socket.io 如何将多个消息组合到一个数据包中.

After a little digging, it appears the problem has come down to how socket.io will group together multiple messages into a single packet.

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

Two issues (#65 #83) depicts the issue at hand and discuss further into detail about the problem.

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

In summary, the socket.IO-objc library did not handle these special cases and always assumed that a packet only contained a single message.

问题 #65 供参考:

Issue #65 for reference:

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

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

长度] [packet_n]

length]�[packet_n]

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

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 字符.

一个修复已经提交,看起来正在审核中截至发稿.

A fix has been submitted earlier and looks to be in review as of this posting.

这篇关于socket.io 发出数据会断开客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 12:47