简体   繁体   中英

Connecting ZeroMQ from browser to server

I am trying to get ZeroMQ working in my web app. On the front end, I am using the JSZMQ library which is supposed to work in-browser (I am aware that most libraries do not). On the Python back end, I am using zmq. The problem is that all the protocols I try throw an error. If I try TCP, as expected the browser throws an error saying "unsupported transport".

According to this SO question JSZMQ should work when the protocol is "ws://". When I try this, the server throws a "Protocol not supported" error immediately on running it. Here is my code:

Client:

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))

Server:

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')

If it matters I am doing multiprocessing for the server, with the zmq object as a global since it's not serializable and can't be passed into functions as an argument.

Why is this not working?

You are a little confused here:

ws:// means http:// or default port 80
wss:// means https:// or default port 443

ws://<server>:<port> means http over that port.

What happens in background is that browser connect to the server over http(s) protocol and upgrade the connection to websocket if it's possible.

Browsers don't allow Raw socket connections, but Websocket ones.

Take a look at 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 (C#) don't yet support the WebSocket transport.

You must take a look at FastAPI Python Framework .

The pattern that you are looking for would be:

[SOCKET CLIENT] --> [FASTAPI SERVER] <--> [ZEROMQ]

This documentation shows how to setup in a single file client websocket and FastAPI server: https://fastapi.tiangolo.com/advanced/websockets/

Your job will be done between websocket.receive_text and 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}")

This framework is so awesome that you can take much more advantage with native Background Tasks: https://fastapi.tiangolo.com/tutorial/background-tasks/

So, you can accept messages from client and send back when it has been done by some ZeroMQ worker.

There are a lot of features that are useful too, like Async Databases, Instant OpenAPI Documentation and so on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM