【问题标题】:Are there Python websocket libraries that expose *socket* functionality?是否有公开 *socket* 功能的 Python websocket 库?
【发布时间】:2015-08-09 02:54:21
【问题描述】:

我要制作一个基于 web 的实时游戏,这需要使用 websockets(请不要在此处指向我的 Flash),因此我需要一个也支持 websockets 的后端服务器。出于多种原因,我决定使用 Python,但是我很难找到合适的库。具体来说,它必须在常规套接字之上实现 websocket,而不是作为不透明的黑盒。因为实际上,websockets 只不过是传统的套接字,除了非常具体的握手。

我已经浏览了许多 Python websocket 支持库,但它们似乎都没有公开 实际套接字 功能,也许我遗漏了一些东西,但我找不到任何东西.它们似乎都实现了您定义套接字解析器的行为(这是整个应用程序的基石)然后启动库的主循环的模式。这不合适,因为 1) 网络循环不会是这里的主循环,2) 套接字仅用于来回传输数据,仅此而已。

那么有没有这样的库可以让我像使用常规套接字一样使用 websockets 而不是抽象的 web 服务器数据端口,或者我真的最好从现有的库中提取有问题的功能并像往常一样继续使用?

【问题讨论】:

  • 但是 websockets 只是套接字。即使在握手之后,websockets 也是帧消息流,而不是字节流。除非您打算自己进行框架(和 TCP 标头操作),否则您不能只将 websocket 套接字用作 TCP 套接字。
  • @abarnert 根据我的阅读,它们只是套接字,带有专门负责 websocket 处理的小额外标头。任何游戏网络库都实现了类似的东西。那里没什么可怕的。
  • 好吧,那你还没有仔细阅读。 Websockets 在 TCP 之上分层了一个框架机制。正如原始文档所说,它“尽可能接近将原始 TCP 暴露给脚本,但不会更接近”。如果你只是把它当作原始 TCP,你将无法与浏览器通信。
  • @abarnet 是的,我明白了。 websockets 本身并没有什么特别之处,这使得它们与常规套接字有任何不同。如果将解析握手和标头放在包装函数下,则常规套接字和 websocket 在使用方面是无法区分的。
  • 不,它们确实是可区分的。您发送和接收消息,而不是字节。这是一个根本的区别。这意味着只是做,例如,epollselect 以查看是否有要阅读的内容不是很有帮助,因为除非有消息的最后一帧,否则仍然没有要处理的内容。

标签: python websocket backend


【解决方案1】:

我认为 Twisted 可能是您需要的:

http://twistedmatrix.com/trac/export/29073/branches/websocket-4173-2/doc/web/howto/websocket.xhtml

这是一篇关于它的深入文章,关于套接字以及如何实现它们你想知道的任何事情:

http://www.fullstackpython.com/websockets.html

我建议您仔细检查一下,然后再决定您想如何去做。我想说没有必要重新发明轮子,除非你想出于学术目的。使用现有的东西有助于更快地完成工作。手动进行也没有利用 Python 拥有如此强大的库这一事实。

【讨论】:

  • Twisted 是我研究过的库之一。特别是,您给出的示例展示了我正在谈论的确切模式 - 套接字解析器对象是整个应用程序的基石。您显然不能将其用于实时视频游戏服务器。
  • 也许你可以看看 asynchio 库?
【解决方案2】:

你的要求没有意义。

您认为,在最初的握手之后,websockets 只是 TCP 套接字。

但他们不是。 websocket 是 messages 的流,而不是 bytes 的流。正如Protocol Overview所解释的那样:

握手成功后,客户端和服务器传回数据 并在本规范中称为概念单位 “消息”。在网络上,一条消息由一个或多个 帧。 WebSocket 消息不一定对应一个 特定的网络层成帧,因为可能是分段消息 由中间人合并或拆分。

一个框架有一个关联的类型。属于同一帧的每一帧 消息包含相同类型的数据。从广义上讲,有 文本数据的类型(解释为 UTF-8 RFC3629 文本),二进制数据(其解释由 应用程序)和控制帧(不打算携带 应用程序的数据,而不是协议级信令, 例如表示应该关闭连接)。这 该协议的版本定义了六种帧类型并留下十种 留作将来使用。

请参阅Design Philosophy 了解它为何如此工作,Data Framing 了解更完整的详细信息。

所以,如果你只是从 websocket 下取出 TCP 套接字并开始发送未成帧的数据,对方不会理解你,只会断开连接。

(您还将破坏大多数代理,因为如果您不使用 TLS,代理支持取决于帧掩码和干净关闭处理,但如果您甚至无法进行最基本的点对点通信,谁在乎?)

当然,您可以在 websockets 之上构建一个 API,它公开面向连接且可靠(如 TCP)但基于数据报(如 UDP)的套接字接口,然后假装你不是使用 websockets……但如果你正在寻找实时、低延迟的网络,那么添加另一层使得当你发现需要优化的东西时很难尽可能接近金属,这似乎不是一个好的选择主意。或者,如果您确实需要,我怀疑您最好构建一个紧密优化的网关,将 localhost UDP 与您的实际服务器和 websocket 通信到您的客户端。


同时,您声称类似asynciotwisted

... 不合适,因为 1) 网络循环不会成为这里的主循环,2) 套接字仅用于来回传输数据,仅此而已。

  1. asynciotwisted(虽然不是大多数其他网络库)都允许您通过手动运行循环的一次迭代而不是永远运行来从另一个循环驱动它们的消息循环。

  2. else 如何在任何地方使用套接字?

【讨论】:

  • @RaidhoCoaxil:这相当于说 TCP 与裸 IP 相同,只是 RFC 为您定义了一组基本标头和规则。有一种感觉,它是真实的,但不是有用的。同时:套接字解析器对象用于 DNS,甚至发生在 HTTP 握手级别之外,那么这与这里有什么关系呢?当然你可以做你自己的 DNS 解析是你想要的,但谁在乎呢?您没有的是 TCP 样式的 recvsend,或者像 selectepoll 这样的选择器——换句话说,它们不是 TCP 套接字。
猜你喜欢
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多