3

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

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

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

我不是很想把它做成一个多线程应用程序,因为我认为它有点过头了。我在 C#/.NET 中使用线程和它们的池进行了很多工作,但我有一种预感,这在这里并不是真正需要的。相反,我认为它会很混乱。

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

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

我假设我可以使用 Twisted 完成几乎任何事情,但我并不真正需要 Twisted 提供的一切。如果我需要加入 Twisted,我会这样做。我实际上找到了 BluetoothSocket 的 Twisted实现。但是,我需要 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 简单。

4

2 回答 2

3

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

你不会的。

  1. API 复杂性:Twisted 的 API 很简单。与某些 FUD 不同,您无需学习数千个 API 即可有效地使用它:Twisted 的核心有一个非常精简的 API,它有几个独立的层和许多明确记录的每层之间的正式接口。如果您知道自己想知道什么(而且看起来确实如此),只要稍加指导,您就可以轻松掌握。此外,作为一个成熟的项目,社区中有很多人可以帮助您的用户跟上进度。
  2. 内存使用:Twisted 一直非常小心地管理它的运行时依赖关系,并且只导入它需要的东西。加载反应器不会加载 IMAP 实现,所以只需导入您需要的内容,不用担心。
  3. 包大小:Twisted 是 2 兆字节。此外,如果您使用任何流行的 UNIX-y 操作系统(Linux、OS X、FreeBSD),您可能已经拥有 Twisted 操作系统包。在许多发行版上,它甚至已经安装了。
  4. 部署麻烦:如果您要担心任何问题,这是要考虑的问题,但是与部署相关的问题确实非常小。“pip install Twisted”工作正常(现在,只要你有一个 C 编译器)。Twisted可与 py2exe、 py2app 和 Debian 打包一起使用,其程度与 Python 中的任何东西一样。真的,任何人唯一遇到的问题就是插件系统,对于许多应用程序,你可以忽略它。
  5. 图书馆冲突:你会没事的。Twisted 竭尽全力兼容任何其他事件循环库曾经提出的每一个愚蠢的想法,无论是 GUI 还是事件循环。你想使用 ZMQ 吗? 去吧。 龙卷风? 当然,无论如何;整合是双向的。 Tornado 本身就支持这种集成。想要使用 Twisted 的阻塞库,但您在主线程上并且不想阻塞? deferToThread已为您服务。想要使用阻塞库中的 Twisted 函数,并且需要阻塞?好的,只需从线程进行阻塞调用

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

于 2012-11-30T15:05:46.093 回答
2

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

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

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

于 2012-11-30T15:56:35.240 回答