nats-io / nats.node

Node.js client for NATS, the cloud native messaging system.
https://nats.io
Apache License 2.0
1.55k stars 163 forks source link

Got error when call publish #623

Closed xzzh999 closed 6 months ago

xzzh999 commented 6 months ago

Observed behavior

code:

  Client.prototype.pubMsg = async function(sub, msg) {
    if(!this.isConnValid()) {
      return
    }
    console.log("pub to " + sub + ", msg: " + msg)
    this.nc.publish(sub, this.codec.encode(`${msg}`))
  }

a single client, when first connect ok( noEcho flag not set ), then subscribe test1, then call pubMsg to test1 got error:

reader closed Error: An object could not be cloned.
    at SubscriptionImpl.callback (VM381 F:\work\Temp-new-ui-electron\test\test-001\.quasar\electron\electron-preload.js:114:11)
    at ProtocolHandler.processMsg (VM404 F:\work\Temp-new-ui-electron\test\test-001\node_modules\nats\lib\nats-base-client\protocol.js:605:17)
    at ProtocolHandler.push (VM404 F:\work\Temp-new-ui-electron\test\test-001\node_modules\nats\lib\nats-base-client\protocol.js:712:22)
    at Parser.parse (VM415 F:\work\Temp-new-ui-electron\test\test-001\node_modules\nats\lib\nats-base-client\parser.js:212:41)
    at ProtocolHandler.<anonymous> (VM404 F:\work\Temp-new-ui-electron\test\test-001\node_modules\nats\lib\nats-base-client\protocol.js:426:45)
    at Generator.next (<anonymous>)
    at fulfilled (VM404 F:\work\Temp-new-ui-electron\test\test-001\node_modules\nats\lib\nats-base-client\protocol.js:5:58)
    at process.processTicksAndRejections (VM290 task_queues:95:5)

but if use nats.ws is ok

Expected behavior

pushlish ok and send msg to self ok

Server and client version

server: 2.10.12 git [121169ea] client: 2.26.0

Host environment

win 10 x64

Steps to reproduce

every time comes up after connect, subscribe then publish

aricart commented 6 months ago

Looks like something happened to your subscription? Check that you didn't exit your iterator with some exception

aricart commented 6 months ago

import {connect} from "nats";

const nc = await connect({servers: ["demo.nats.io"]});
const sub = nc.subscribe("helloworld");

(async () => {
    for await(const m of sub) {
        console.log(m.subject, m.string());
    }
})();

let i = 0;
setInterval(() => {
    nc.publish("helloworld", `${i++}`);
}, 250);
aricart commented 6 months ago

Reopen if you have better information. As it is from that stack, the client is simply pushing a message into the subscription - something else is trying to clone something, but that is not part of the code base that I can see.

aricart commented 6 months ago

Note that you can only run nats code from the app side (node.js).

xzzh999 commented 6 months ago

@aricart thanks u reply

Note that you can only run nats code from the app side (node.js).

yes, i known, and it is. i use electron and call node.js interface through electron-preload.js bridge.

i dont use for await(const m of sub) { ... } to recv subscribe msg, but use callback like this:

Client.prototype.subscribeMsg = async function(sub, callback) {
    if(!this.isConnValid()) {
      return
    }
    console.log("subscribe: ", sub)
    this.nc.subscribe(sub, {callback: (err, msg)=> {
      callback(err, msg)
    }})
  }
xzzh999 commented 6 months ago

and when i change to this as u code above:

  Client.prototype.subscribeMsg = async function(sub, callback) {
    if(!this.isConnValid()) {
      return
    }
    console.log("subscribe: ", sub)
    const subObj = this.nc.subscribe(sub);

    (async () => {
      for await(const m of subObj) {
          console.log(m);
          callback('', this.codec.decode(m.data))
      }
    })();

everything works fine, no any errors, why callback not working?

xzzh999 commented 6 months ago

I see now, msg param in callback in node.js can't clone to the randering js 's context, thank u again.