如何在Android活动之间共享socket.io连接?

时间:2015-11-13 11:16:29

标签: android node.js android-activity socket.io connection-pooling

在socket.io Android客户端example项目中,我们读到了:

  

IO.socket()使用默认选项返回http://chat.socket.io的套接字。请注意,该方法会缓存结果,因此您始终可以从任何Activity或Fragment获取相同的Socket实例。

所以我决定测试一下,因为我服务器上打开的套接字数量不等于客户端数量。

我使用了以下服务器:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
    res.sendfile('index.html');
});

io.on('connection', function(socket){
    console.log('- connect event '+socket.id);
    socket.on('disconnect', function () {
        console.log('- disconnect event from id '+socket.id);
    });
});

http.listen(3000, '0.0.0.0', function(){
    console.log('. listening on *:3000');
});

开发了一个非常简单的Android应用程序,它包含两个活动,每个活动都会打开与同一服务器地址的socket.io连接,并且只允许在活动之间切换。

我启动服务器并启动应用程序,这是我得到的输出。

. listening on *:3000
( now I launch the app, opens Activity A )
- connect event 1FIizV3QMdGmnYUQAAAA
( I switch from Activity A to Activity B )
- connect event IzllGFxbpzI5NPNiAAAB
( I switch back from Activity B to Activity A )
- connect event pNt8Yvom5Rih_-01AAAC
- disconnect event from id 1FIizV3QMdGmnYUQAAAA
- disconnect event from id IzllGFxbpzI5NPNiAAAB

这个简单的测试表明,当活动中的onDestroy事件关闭回调时,套接字连接被破坏,当我恢复活动时,会打开一个新的套接字连接,但它与上面提到的so you can always get a same Socket instance for an url from any Activity or Fragment相矛盾,因为似乎正在创建新实例。

问题

似乎多重活动模型在Android开发中很常见(很多人认为一次又一次地简单地更改碎片是低效的),如何有效地共享这些活动之间的套接字连接,以便服务器可以具有相同的客户端的套接字连接,无论它包含多少活动?

我考虑的选项是创建一个BoundService来处理套接字连接的所有回调和事件,并且所有活动都可以共享此服务,但是我找不到与这种服务进行通信的有效方式。在这种情况下,IPC(进程间通信)可能会非常缓慢,特别是如果它基于Intents。

我希望我可以获得一些帮助,让我的应用更专业,而且对其他人也有用。

1 个答案:

答案 0 :(得分:2)

您可以使用Service来处理套接字,并使用Binder通过任意方法而不是Intents与服务进行通信。我假设你已经知道如何使用已启动和/或绑定的服务,如果没有 - read the guide

您需要覆盖Service的onBind回调并返回Binder类的自定义子类,该子类公开用于控制套接字,注册回调等的API。

以下是Binder的代码可能如下所示:

private final IBinder socketBinder = new SocketBinder();

@Override
public IBinder onBind(Intent intent) {
    return socketBinder;
}

public class SocketBinder extends Binder {
    // Now you have access to all your Service's public methods
    public SocketService getService() {
        return SocketService.this;
    }
}