【问题标题】:Using a BluetoothSocket in ZeroMQ/Tornado ioloop, or maybe in Twisted?在 ZeroMQ/Tornado ioloop 或 Twisted 中使用 BluetoothSocket?
【发布时间】:2012-11-30 09:43:36
【问题描述】:

我正在使用 PyBluez 通过蓝牙连接到设备。它工作得很好。该设备正在使用 SPP,我使用 BluetoothSocket (RFCOMM) 进行连接。

基本交互是:发送init命令->接收确认;发送开始命令 -> 接收连续数据;发送停止命令 -> ...

我需要能够从另一个应用程序控制应用程序:启动、停止......我在想 ZeroMQ 或者 Tornado 和 HTTP/REST ifc。

我不太热衷于将此应用程序制作为多线程应用程序,因为我认为它有点矫枉过正。我在 C#/.NET 中使用线程和它们的池进行了很多工作,但我有一种预感,这在这里并不是真正需要的。反而觉得会比较乱。

但是,我需要能够通过 ZeroMQ/REST/... 处理命令(例如“开始”、“停止”),同时不断接收数据并偶尔发送数据包。

由于我对 Python 很陌生,我不知道如何实现它。我有几个想法:BluetoothSocket 可以连接到 ZeroMQ/Tornado IOLoop 吗?

我假设我可以使用 Twisted 完成几乎任何事情,但我并不真正需要 Twisted 提供的一切。如果我需要加入 Twisted,我会这样做。我实际上找到了一个 Twisted implementation 的 BluetoothSocket。但是,我需要 Twisted 吗?

我尝试过使用 Tornado IOLoop。没有抛出异常,但另一方面没有数据被接收或发送:

def eventhandler(s, events, error = None):
    if events & ioloop.IOLoop.READ:
        print 'Socket read: %r' % s.recv(1024)
    elif events & ioloop.IOLoop.ERROR:
        print 'Socket error!'

events = ioloop.IOLoop.READ | ioloop.IOLoop.ERROR
self._loop.add_handler(self._socket.fileno(), eventhandler, events)

我真的不知道我现在在做什么。我最终会找到方法,但需要一个提示来说明前进的方向。

广泛的 Google-fu 没有找到太多有用的信息,所以我现在在这里问。

编辑:我目前正在查看“gevent”。至少看起来比 Twisted 简单。

【问题讨论】:

  • 为什么你认为线程或 Twisted 是“矫枉过正”?什么是软件中的“矫枉过正”?你不会把你的问题磨成尘土,以至于随风飘散,让你失业。您不会通过将 Twisted 或线程应用于“简单”问题来用完世界上所有的 Twisted 或线程。为什么你认为这是一个简单的问题呢?是什么使它比任何其他并发 I/O 问题更容易? :) 特别是因为听起来您认为您已经知道如何使用 Twisted 解决这个问题,为什么要花时间尝试找到一个 没有它的解决方案?
  • 公平点!我不知道如何在 Twisted 中做到这一点,但正如我在问题中指出的那样,我找到了一个实现。我正在尝试在这里学习Python,但我不知道这是一种优雅的方式。当然,我可以启动线程。我什至可以在自己设计的循环中处理接收,不时轮询 ZeroMQ 以获取命令。我不想自动使用一个庞大的库,后来发现它可以用几行代码和一个 ioloop 来完成。此外,无论如何我可能会使用 ZeroMQ 和/或 Tornado。那里可以处理吗?那么好多了。
  • 谢谢。这有点清楚了。 :)

标签: python bluetooth twisted tornado zeromq


【解决方案1】:

您应该只使用 Twisted。您真正的问题似乎是关于 Twisted 的规模和资源利用率;您是否会为使用它而在应用程序中支付不合理的成本,无论是在 API 复杂性、内存、磁盘上的包大小、部署麻烦还是与您可能想要使用的其他库的冲突方面。

你不会的。

  1. API 复杂性:Twisted 的 API 很简单。与某些 FUD 不同,您无需学习数千个 API 即可有效地使用它:Twisted 的核心有一个非常精简的 API,它有几个独立的层和许多明确记录的每层之间的正式接口。如果您知道自己想知道什么(而且看起来确实如此),只要稍加指导,您就可以轻松掌握。此外,作为一个成熟的项目,社区中有很多人可以帮助您的用户跟上进度。
  2. 内存使用:Twisted 一直非常小心地管理它的运行时依赖关系,并且只导入它需要的东西。加载 reactor 不会加载 IMAP 实现,因此只需导入您需要的内容,无需担心。
  3. 包大小:Twisted is two megabytes。此外,如果您使用任何流行的 UNIX-y 操作系统(Linux、OS X、FreeBSD),您可能已经拥有 Twisted 操作系统包。在许多发行版中,它甚至已经安装了。
  4. 部署麻烦:如果您要担心任何问题,这是要考虑的问题,但与部署相关的问题确实非常小。 “pip install Twisted”工作正常(现在,as long as you have a C compiler)。 Twisted works with py2exe、py2app 和 Debian 打包 to the extent that anything in Python does。确实,任何人唯一遇到的问题就是插件系统,对于许多应用程序,您可以忽略它。
  5. 图书馆冲突:你会完全没事的。 Twisted 不遗余力地兼容任何其他事件循环库曾经提出的每一个愚蠢的想法,无论是 GUI 还是事件循环。你想使用 ZMQ 吗? Go for it.龙卷风? Sure, whatever;整合是双向的。 Tornado itself supports such integration。想要使用 Twisted 的阻塞库,但您在主线程上并且不想阻塞? deferToThread 已为您服务。想要使用阻塞库中的 Twisted 函数,并且您需要阻塞?好的,只需发送blocking call from a thread

我希望这能消除您对 Twisted 是“矫枉过正”的任何误解。

【讨论】:

【解决方案2】:

这是一个没有直接经验的观点,但是我做了一些研究,您在选择时需要考虑的是阻塞与非阻塞 IO。

从快速阅读来看,PyBluez 模块(库)不支持异步 IO,这意味着您最终需要深入挖掘库以在 Tornado 或 Twisted 中正确处理所有读写位。

如果这是我的项目,我可能会做的是将 PyBluez 库放入它自己的线程中,然后将一些队列与它交互回 Tornado(我是 Tornado 粉丝)。现在只是如何将蓝牙事件传递到您的主 IOLoop 的问题。您确实有两个选择,将一个套接字连接到自己,因为 IOLoop 通常在选择中被阻塞。或者设置一个定时器,每 100 毫秒回调一次,以检查蓝牙队列中是否有任何需要处理的活动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2013-10-30
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    相关资源
    最近更新 更多