Socket.io 不会按需关闭套接字(并且不允许我的 swift 应用程序再次重新连接到 node.js 服务器)

Posted

技术标签:

【中文标题】Socket.io 不会按需关闭套接字(并且不允许我的 swift 应用程序再次重新连接到 node.js 服务器)【英文标题】:Socket.io does not close the socket on demand (and does not allow my swift app to reconnect again to the node.js server) 【发布时间】:2016-09-26 08:07:14 【问题描述】:

我正在使用socket.io 库,我已经实现了服务器端(在node.js 中)。我尝试遵循一个非常简单的场景:

1) 用户建立连接

2) 用户连接到房间

3) 用户断开连接

4) 用户重新连接

我在客户端使用 ios 应用程序(用 swift 编写)。

我的服务器代码如下:

io.on('connection', function(clientSocket)
    console.log('a user connected here');

    clientSocket.on('disconnect', function()
        console.log('user disconnected');
    );

    clientSocket.on('connectUser', function(username)
        clientSocket.join(username);
        console.log('user ' + username + ' connected to the room.');
    );

现在在我的客户端,我创建了一个负责处理所有套接字内容的类:

class SocketIOManager: NSObject 
static let sharedInstance = SocketIOManager()
var socket: SocketIOClient = SocketIOClient(socketURL: NSURL(string: serverURL)!, options: [.ForceNew(true)])

override init() 
    super.init()


func establishConnection() 
    socket.connect()



func closeConnection() 
    socket.disconnect()


func connectToServerWithNickname(nickname: String) 
    print("CONNECTING TO SOCKET SERVER \(nickname)")
    socket.emit("connectUser", nickname)


现在 - 进一步 - 在我的 swift 应用程序中(applicationDidBecomeActive)我打电话给establishConnection(),然后是SocketIOManager.sharedInstance.connectToServerWithNickname(username)

在我的服务器控制台中,我看到:

a user connected here
user 571fc6818451630f5becda9c connected to the room.

在我的appDelegate我实现了这个功能:

func applicationWillResignActive(application: UIApplication) 
    SocketIOManager.sharedInstance.closeConnection()
    print("closing sockets")

所以现在,当我将应用程序置于后台时,我会看到 closing sockets,而在我的服务器控制台中,我会看到 user disconnected

现在是主要问题 - 我想在用户返回应用程序时重新连接用户。因此我实现了这个方法:

func applicationDidBecomeActive(application: UIApplication) 

    print("application is back to life")

    SocketIOManager.sharedInstance.establishConnection()
    SocketIOManager.sharedInstance.connectToServerWithNickname(username)


但是现在当我从后台唤醒应用程序时,在我的服务器控制台中我只看到a user connected here。所以这个消息:

user 571fc6818451630f5becda9c connected to the room.

丢失,我认为这是因为我的应用程序没有重新连接到套接字。

根据我的阅读,socket.io 确实有问题,人们建议切换到其他库,但我还是想使用它。我在 github https://github.com/socketio/socket.io-client/issues/251 上发现了这个问题,他们建议在客户端使用特定参数。在这个插件的 swift https://github.com/nuclearace/Socket.IO-Client-Swift 页面之后,我找到了特定的标志:

case ForceNew(Bool) // Will a create a new engine for each connect. Useful if you find a bug in the engine related to reconnects

这就是为什么我在客户端构建我的套接字:

var socket: SocketIOClient = SocketIOClient(socketURL: NSURL(string: serverURL)!, options: [.ForceNew(true)])

但是是的,即使在Socket.IO-Client-Swift 库的官方代码中,在断开连接方法上方也有注释:

/// Disconnects the socket. Only reconnect the same socket if you know what you're doing.
/// Will turn off automatic reconnects.
public func disconnect() 
    DefaultSocketLogger.Logger.log("Closing socket", type: logType)

    reconnects = false
    didDisconnect("Disconnect")

有人知道我该如何处理吗?我想在我的应用程序每次进入后台时关闭套接字,并在我的应用程序进入前台时再次连接到它。谢谢!

【问题讨论】:

【参考方案1】:

在 applicationWillEnterForeground 中添加您的代码

SocketIOManager.sharedInstance.establishConnection() SocketIOManager.sharedInstance.connectToServerWithNickname(用户名)

【讨论】:

以上是关于Socket.io 不会按需关闭套接字(并且不允许我的 swift 应用程序再次重新连接到 node.js 服务器)的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io 问题仅在移动设备上

如何在Socket.IO中一次性离开套接字连接的所有房间[关闭]

Socket.io - 套接字拆分成房间 [关闭]

将 Socket.io 与 Sequelize 一起使用

断开连接/错误时清除 socket.io 缓冲区

socket.io 错误 - Web 套接字连接在建立连接之前关闭