Skip to content

PAIR client cannot send messages to server freely #435

@kakyoism

Description

@kakyoism

Describe the bug

Between two processes, my client socket of a PAIR pattern cannot send messages outside of its async loop for incoming messages.

Reproducing

I'm using ZeroMQ.js to communicate between my app's frontend (electron) and backend (c++). The backend is launched as a child process by the frontend.

The pattern in use is zmq.Pair. And the client, a.k.a. the frontend, can receive messages from the server, a.k.a. the backend, just fine.

class UiBridge {
    constructor(address="tcp://127.0.0.1:25555") {
        this.address = address;
        this.socket = new zmq.Pair();
    }

    async Start() {
        await this.socket.connect(this.address);

        console.log("frontend: Connected to backend.");

        const listen = async () => {
            for await (const [backendRequest] of this.socket) {
              switch (backendRequest.toString()) {
                case 'msg1':
                  onMsg1();

                  // THIS Send works!
                  // the receiver gets the reply.

                  this.Send("reply");
                  break;

                case 'term':
                  this.Stop();
                  break;

                default:
                  console.error(`undefined message from backend: ${backendRequest}`);
              }
            }
        }
      
        listen();
    }
    
    async Stop() {
        if (!this.socket.closed) {
          this.socket.close()
        }
    }

    async Send(cmd) {
        try {
            await this.socket.send(cmd);
            alert(`sent msg: ${msg}`);
        } catch (err) {
            alert(`send failed due to : ${err}`);
        }
    }
}

Note that if I send messages inside the listening loop on receiving any message from the other side, then the send works.

Wrong behaviour

But if I send messages outside of the listening loop anywhere else in the frontend code, then the other end never receives the sent message, and no exceptions are caught. Like in a button callback

function onToggleButton() {

    // This is never received!

    gUiBridge.Send("from frontend");
}

The button callback is triggered and I see the alert coming up. I've made sure that I can already receive messages from the server before clicking on buttons.

Expected behavior

I expect to be able to call await socket.send() anywhere in my frontend process and have the backend receive the message under PAIR, so that only one address is used to have bidirectional comm between my frontend and backend.

Workaround

I had to create another pair of PUSH/PULL to send messages from anywhere of my frontend to backend, so that I'm not blocked by this issue. But this is suboptimal.

Tested on

  • OS: [macOS 10.15.7]
  • ZeroMQ.js version: [v6.0.0-beta.6]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions