跳转到主要内容

Tornado框架上的Socket.io服务器实现

项目描述

贡献者

致谢

SocketTornad.IO项目的作者

这是在Tornado框架之上实现Socket.IO实时传输库的示例。

简要背景

有一个库已经实现了使用Tornado框架的Socket.IO集成 - SocketTornad.IO,但它尚未完成,有多个已知错误,并且结构不佳。

暴风IO与SocketTornad.IO库在以下方面有所不同

  • 更简单的内部设计,更容易维护/扩展

  • 没有外部依赖(除了Tornado本身和python < 2.6上的simplejson)

  • 正确处理轮询传输的on_open/on_close事件

  • 正确的Socket.IO协议解析器

  • 正确的Unicode支持

  • 积极维护

介绍

为了开始使用暴风IO库,您需要了解一些关于Tornado工作方式的基本概念。如果您不了解,请阅读Tornado教程,可以在这里找到。

如果您熟悉Tornado,请按照以下步骤添加对Socket.IO的支持到您的应用程序

1. 从tornadio.SocketConnection类派生并重写on_message方法(on_open/on_close是可选的)

class MyConnection(tornadio.SocketConnection):
  def on_message(self, message):
    pass

2. 创建处理对象以处理所有与socket.io传输相关的功能

MyRouter = tornadio.get_router(MyConnection)

3. 将您的处理路由添加到Tornado应用程序

application = tornado.web.Application(
  [MyRouter.route()],
  socket_io_port = 8000)
  1. 启动您的应用程序

  2. 您的socket.io服务器正在端口8000上运行。很简单,对吧?

附加功能

SocketConnection类提供了三个可覆盖的方法

  1. on_open 在新客户端连接建立时调用。

  2. on_message 在收到来自客户端的消息时调用。如果客户端发送了JSON对象,它将被自动解码为适当的Python数据结构。

  3. on_close 在客户端连接关闭时被调用(由于网络错误、超时或客户端断开连接)

每个 SocketConnection 都有一个 send() 方法,用于向客户端发送数据。输入参数可以是以下之一:

  1. 字符串/unicode字符串 - 原样发送(尽管使用utf-8编码)

  2. 任意Python对象 - 自动编码为JSON字符串

  3. Python对象/字符串的列表 - 使用上述规则之一编码为一系列的socket.io消息。

配置

您可以通过将设置作为字典对象传递给 get_router 函数来配置您的处理程序。

  • enabled_protocols:这是一个服务器将响应请求的socket.io协议列表。可能的选择有:

  • websocket:HTML5 WebSocket传输

  • flashsocket:Flash模拟的websocket传输。需要在端口843上运行Flash策略服务器。

  • xhr-multipart:与两个连接一起工作 - 使用多部分传输编码的长期GET连接接收服务器更新,并使用单独的POST请求从客户端发送数据。

  • xhr-polling:用于从服务器读取数据的长期轮询AJAX请求,以及用于向服务器发送数据的POST请求。如果消息可用,它将通过打开的GET连接(然后关闭)发送,否则在服务器端排队。

  • jsonp-polling:类似于 xhr-polling,但通过JSONp推送数据。

  • htmlfile:仅IE。创建HTMLFile控件,通过一个持久连接从服务器读取数据。使用POST请求将数据发送回服务器。

  • session_check_interval:指定TornadIO多久检查一次会话容器中的过期会话对象。以秒为单位。

  • session_expiry:指定会话过期间隔,以秒为单位。对于轮询传输,这是实际上允许在GET请求之间允许的最大时间,以认为虚拟连接已关闭。

  • heartbeat_interval:持久传输的心跳间隔。指定服务器应该多久向客户端发送一次心跳事件。

  • xhr_polling_timeoutxhr-polling传输的长期运行的XHR连接的超时时间,以秒为单位。如果在这段时间内没有数据可用,则将在服务器端关闭连接,以避免客户端超时。

资源

您不是限制每个服务器仅有一个连接类型 - 您可以在一个服务器实例中为不同的客户端提供服务。

默认情况下,所有socket.io客户端使用相同的资源 - 'socket.io'。您可以通过将 resource 参数传递给 get_router 函数来更改资源

ChatRouter = tornadio.get_router(MyConnection, resource='chat')

在客户端,通过将 resource 参数传递给 io.Socket 构造函数来提供您要连接的资源

sock = new io.Socket(window.location.hostname, {
             port: 8001,
             resource: 'chat',
           });

如前所述,您可以通过为每种连接类型具有唯一的资源来拥有尽可能多的连接类型

ChatRouter = tornadio.get_router(ChatConnection, resource='chat')
PingRouter = tornadio.get_router(PingConnection, resource='ping')
MapRouter = tornadio.get_router(MapConnection, resource='map')

application = tornado.web.Application(
  [ChatRouter.route(), PingRouter.route(), MapRouter.route()],
  socket_io_port = 8000)

额外参数

如果您的应用程序需要某种用户身份验证,您有两种选择

  1. 将身份验证令牌作为客户端的第一条消息发送

  2. 将身份验证令牌作为 resource 参数的一部分提供

TornadIO支持通过 socket.io 资源传递的额外数据。

您可以在 get_router 函数的 extra_re 参数中提供正则表达式,匹配的数据可以在您的 on_open 处理程序中作为 kwargs['extra'] 访问。例如

class MyConnection(tornadio.SocketConnection):
  def on_open(self, *args, **kwargs):
    print 'Extra: %s' % kwargs['extra']

ChatRouter = tornadio.get_router(MyConnection, resource='chat', extra_re='\d+', extra_sep='/')

客户端

sock = new io.Socket(window.location.hostname, {
             port: 8001,
             resource: 'chat/123',
           });

如果您运行此示例并使用示例客户端连接,您应该看到打印出“Extra: 123”。

启动

最佳方式:SocketServer

我们提供了定制版本的HttpServer(毫不夸张地借鉴了SocketTornad.IO库),它简化了您TornadIO服务器的启动。

要启动它,请执行以下操作(假设您已创建应用程序对象)

if __name__ == "__main__":
  socketio_server = SocketServer(application)

如果需要,SocketServer将自动启动Flash策略服务器。

迈向更大规模

因此,您已经完成了应用程序的编写,并希望与全世界分享,所以您开始考虑可扩展性、部署选项等。

大多数Tornado服务器都部署在nginx后面,nginx也用于提供静态内容。这对于TornadIO来说效果并不好,因为nginx不支持HTTP/1.1,不支持websockets,而XHR-Multipart传输也无法工作。

因此,为了负载均衡您的TornadIO实例,请使用替代解决方案,如HAProxy。然而,HAProxy不支持Windows,因此如果您计划在Windows平台上部署解决方案,您可能需要考虑MLB

可扩展性是完全不同的概念。作为开发者,您需要设计应用程序的可扩展架构。

例如,如果您需要从多个物理进程(甚至服务器)中创建一个大型虚拟服务器,您必须想出某种同步机制。这可能是一个共同的会合点(同时也是故障点),如memcached、redis等。或者您可能想要使用某种传输机制在服务器之间进行通信,例如基于AMQPZeroMQ或使用您的协议的普通套接字。

例如,使用消息队列,您可以把TornadIO视为客户端和服务器后端之间的消息网关。

示例

聊天室示例

SocketTornad.IO库提供了一个聊天室示例应用程序,由swanson贡献。它在examples/chatroom目录中。

Ping示例

一个简单的ping/pong示例,用于衡量网络性能。它在examples/ping目录中。

传输示例

一个简单的ping/pong示例,具有类似聊天的界面,可以选择传输方式。它在examples/transports目录中。

项目详情


下载文件

下载适合您平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。

源分发

TornadIO-0.0.5.zip (25.1 kB 查看哈希值)

上传时间

支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面