多个服务器之间的Socket.io连接分配

时间:2013-08-16 06:44:07

标签: python socket.io gevent-socketio

我正在研究数据库设计工具(python,gevent-socket.io)。在这些工具中,多个用户可以讨论一个数据库模型,接收运行时的更改。为了支持此功能,我正在使用socket.io。我想扩展一些容易处理socket.io连接的服务器。最简单的方法是设置nginx以选择基于模型ID的服务器。

我想要模块方法,其中模型ID除以服务器数量。因此,如果我有3个节点,模型1将首先处理,2 - 第二个,3 - 第三个,4 - 再次首先等。

我对模型加载的请求看起来像/ models /,所以这里没问题 - 可以解析参数来找到服务器来处理它。但是在加载模型页面之后,JS尝试建立连接:

var socket = io.connect('/models', {
            'reconnection limit': 4000
        });

它访问默认端点,因此服务器收到以下请求:

http://example.com/socket.io/1/xhr-pooling/111111?=1111111

为了处理它,我以这种方式创建应用程序:

SocketIOServer((app.config['HOST'], app.config['PORT']), app, resource='socket.io', transports=transports).serve_forever()

然后

@bp.route('/<path:remaining>')
def socketio(remaining):
    app = current_app._get_current_object()
    try:
        # Hack: set app instead of request to make it available in the namespace.
        socketio_manage(request.environ, {'/models': ModelsNamespace}, app)
    except:
        app.logger.error("Exception while handling socket.io connection", exc_info=True)
    return Response()

我想将其更改为

http://example.com/socket.io/<model_id>/1/xhr-pooling/111111?=1111111

能够在ngnix中选择正确的服务器。怎么做?

更新

我还想在尝试建立连接时检查用户权限。我想在socketio(剩余)方法中做到这一点,但是,我需要知道他试图访问的模型。

更新2

我实现了权限验证程序,从HTTP_REFERER获取了model_id。似乎,它只是包含模型标识符的请求的一部分(值的示例:http://example.com/models/1/)。

1 个答案:

答案 0 :(得分:2)

第一个想法 - 告诉客户端当前时间的可用服务器。 此外,您可以按优先级为客户端生成服务器列表,只需按顺序将它们放入javascript生成的数组中。 这个答案意味着您的服务器可以在任何型号上应答,您可以通过更改新客户端的生成列表中的服务器顺序来控制服务器负载。

我认为这是更灵活的方式。但是如果你想 - 你可以在nginx中解析查询字符串并在任何底层服务器上路由请求 - 只需要一个“模型id-server port”关系表

更新:只是考虑一下你的任务。并找到另一个解决方案。生成客户端网页时,内联服务器可以在某个地方计算js。然后,当您请求模型更新时,只需使用另一个参数

serverId = modelId%ServersCount;

这将是nginx中路由的服务器标识符。 然后在nginx配置中,您可以使用简单的解析查询字符串,并通过serverId参数找到服务器的路由请求。

在“元语言”中它将是

  1. 将参数serverId获取到var $ servPortSuffix
  2. 路由请求到localhost:80 $ servPortSuffix
  3. 或其他路线创意。

    您可以通过

    向socket.io添加其他GET参数
    io.connect(url, {query: "foo=bar"})