将 ZeroMQ 从浏览器连接到服务器
Connecting ZeroMQ from browser to server
我正在尝试让 ZeroMQ 在我的网络应用程序中运行。在前端,我使用的是应该在浏览器中工作的 JSZMQ 库(我知道大多数库都不能)。在 Python 后端,我使用的是 zmq。问题是我尝试的所有协议都会抛出错误。如果我尝试 TCP,正如预期的那样,浏览器会抛出一条错误消息“不受支持的传输”。
根据 this SO question JSZMQ 应该在协议为“ws://”时工作。当我尝试这样做时,服务器立即在 运行 上抛出“不支持协议”错误。这是我的代码:
客户:
import * as zmq from 'jszmq'
const socket = new zmq.Pull()
socket.connect('ws://127.0.0.1:3000')
socket.on('message', msg => console.log(msg))
服务器:
import zmq
context = zmq.Context()
sock = context.socket(zmq.PUSH)
sock.bind('ws://127.0.0.1:3000') # This is what throws the error
sock.send('hello')
如果这很重要,我正在为服务器进行多处理,将 zmq 对象作为全局对象,因为它不可序列化并且不能作为参数传递给函数。
为什么这不起作用?
你这里有点糊涂:
ws:// means http:// or default port 80
wss:// means https:// or default port 443
ws://<server>:<port> means http over that port.
后台发生的事情是浏览器通过 http(s) 协议连接到服务器,并在可能的情况下将连接升级到 websocket。
浏览器不允许 Raw 套接字连接,但是 Websocket。
看看https://github.com/zeromq/jszmq#compatibility-with-zeromq :
Compatibility with ZeroMQ
WebSocket transport added to zeromq recently, and it is only available
when compiling from source.
Other ports of zeromq, like NetMQ (C#) and JeroMQ (Java) don't yet
support the WebSocket transport.
你一定要看看FastAPI Python Framework。
您正在寻找的模式是:
[SOCKET CLIENT] --> [FASTAPI SERVER] <--> [ZEROMQ]
本文档展示了如何在单个文件客户端 websocket 和 FastAPI 服务器中进行设置:
https://fastapi.tiangolo.com/advanced/websockets/
您的工作将在 websocket.receive_text 和 websocket.send_text 之间完成。
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
# --> ZeroMQ Code Here <--
await websocket.send_text(f"Message text was: {data}")
这个框架非常棒,您可以利用本机后台任务获得更多优势:
https://fastapi.tiangolo.com/tutorial/background-tasks/
因此,您可以接受来自客户端的消息,并在某些 ZeroMQ worker 完成后发回。
还有很多有用的功能,例如异步数据库、即时 OpenAPI 文档等。
我正在尝试让 ZeroMQ 在我的网络应用程序中运行。在前端,我使用的是应该在浏览器中工作的 JSZMQ 库(我知道大多数库都不能)。在 Python 后端,我使用的是 zmq。问题是我尝试的所有协议都会抛出错误。如果我尝试 TCP,正如预期的那样,浏览器会抛出一条错误消息“不受支持的传输”。
根据 this SO question JSZMQ 应该在协议为“ws://”时工作。当我尝试这样做时,服务器立即在 运行 上抛出“不支持协议”错误。这是我的代码:
客户:
import * as zmq from 'jszmq'
const socket = new zmq.Pull()
socket.connect('ws://127.0.0.1:3000')
socket.on('message', msg => console.log(msg))
服务器:
import zmq
context = zmq.Context()
sock = context.socket(zmq.PUSH)
sock.bind('ws://127.0.0.1:3000') # This is what throws the error
sock.send('hello')
如果这很重要,我正在为服务器进行多处理,将 zmq 对象作为全局对象,因为它不可序列化并且不能作为参数传递给函数。
为什么这不起作用?
你这里有点糊涂:
ws:// means http:// or default port 80
wss:// means https:// or default port 443
ws://<server>:<port> means http over that port.
后台发生的事情是浏览器通过 http(s) 协议连接到服务器,并在可能的情况下将连接升级到 websocket。
浏览器不允许 Raw 套接字连接,但是 Websocket。
看看https://github.com/zeromq/jszmq#compatibility-with-zeromq :
Compatibility with ZeroMQ
WebSocket transport added to zeromq recently, and it is only available when compiling from source.
Other ports of zeromq, like NetMQ (C#) and JeroMQ (Java) don't yet support the WebSocket transport.
你一定要看看FastAPI Python Framework。
您正在寻找的模式是:
[SOCKET CLIENT] --> [FASTAPI SERVER] <--> [ZEROMQ]
本文档展示了如何在单个文件客户端 websocket 和 FastAPI 服务器中进行设置: https://fastapi.tiangolo.com/advanced/websockets/
您的工作将在 websocket.receive_text 和 websocket.send_text 之间完成。
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
# --> ZeroMQ Code Here <--
await websocket.send_text(f"Message text was: {data}")
这个框架非常棒,您可以利用本机后台任务获得更多优势: https://fastapi.tiangolo.com/tutorial/background-tasks/
因此,您可以接受来自客户端的消息,并在某些 ZeroMQ worker 完成后发回。
还有很多有用的功能,例如异步数据库、即时 OpenAPI 文档等。