使用 WebSockets 扩展 Flask REST API

Pie*_*ens 5 flask flask-socketio flask-restplus

我目前正在扩展使用 Flask-RESTPlus 创建的现有 REST API,并支持 WebSocket。这个想法是创建一个符合 Web 事物模型的Web 事物(网关)。我的用例中的“事物”是动态添加或删除的。

当前设置允许消费者使用对/thingId/properties/temperature的 HTTP GET 请求从 Thing(例如温度传感器)获取最新值。这些值实际上是从 Kafka 消费的,并临时存储在 Redis 中。

现在我想知道如何扩展此设置并允许消费者不仅轮询最新值,而且使用 WebSockets 订阅事物的属性。我有一个工作解决方案,我为每个属性创建“房间”,但这需要两个单独的服务器和端点的重复。

对于 REST 我有

@app.route('/<thingId>/properties/<propertyId>')
    # get latest datapoint
    return latestDatapoint
Run Code Online (Sandbox Code Playgroud)

对于 Flask-SocketIO 我有

@socketio.on('join')
def on_join(data):
    username = data['username']
    room = data['room'] # e.g. /thingId/properties/temperature
    join_room(room)
    send(username + ' has entered the room.', room=room)
Run Code Online (Sandbox Code Playgroud)

然后我将数据转发到正确的房间,因为它来自 Kafka。在客户端,我需要连接到 WebSocket 服务器并加入房间

socket.on('connection', function(socket){
  socket.emit('join', 'some room');
});
Run Code Online (Sandbox Code Playgroud)

此实现有效,但我强烈希望有如下图所示的替代工作流程,其中客户端连接到 REST API 中使用的相同端点,但使用 WebSocket 协议而不是加入房间等。 网络事物订阅

您是否知道这是否已经存在或是否可行?

Mig*_*uel 5

我有一个工作解决方案,我为每个属性创建“房间”,但这需要两个单独的服务器和端点的重复。

Socket.IO 服务器和您的 HTTP 服务器不一定需要分开,在所有支持的配置中,您可以使用单个服务器托管 HTTP 和 Socket.IO 应用程序。

我也没有看到端点重复,但这可能是因为您将 Socket.IO 事件处理程序视为端点,而实际上它们不是。对于 Socket.IO,HTTP 意义上只有一个端点,因为所有 Socket.IO 流量都在单个 URL 上传输。您的事件处理程序就是在 Socket.IO 端点上弹出某些事件时调用的函数。

客户端连接到 REST API 中使用的相同端点,但使用 WebSocket 协议而不是加入房间等。

所以你想让你的客户端为它想要观看的每件事建立一个单独的 WebSocket 连接?这似乎有点资源密集型,对我来说不是很可扩展。如果客户端需要监视 100 个事物,那么它必须维护 100 个 WebSocket 连接。请记住,大多数浏览器都会限制它们一次可以打开的 WebSocket 连接数,包括每页和全局。

Socket.IO 是建立在 WebSocket 和 HTTP 之上的更高级别的协议。如果您仍然更喜欢直接使用 WebSocket,那么您可以使用任何可用的开源 WebSocket 服务器并使用它而不是 Socket.IO 来实现您的应用程序。以下是我最想到的 Python 的几个选项:

您将失去 Socket.IO 提供的一些非常方便的东西:

  • 自动重新连接
  • 通过长轮询自动支持非 WebSocket 客户端
  • 基于事件的调度
  • 客房

所以你需要确保这些不是重要的特性,或者你可以直接在 WebSocket 服务器上自己实现它们。