4ib3r / StompBrokerJS

NodeJS StompBroker
MIT License
36 stars 28 forks source link

HeartBeatOn does not work #33

Open Tarosweet opened 1 year ago

Tarosweet commented 1 year ago

When I use this function, I try to send a heartbeat to the client, but the following usage does not work:

const http = require('http');
const StompServer = require('stomp-broker-js');
// const node_static = require('node-static');
// const static_directory = new node_static.Server(__dirname);

const server = http.createServer((request, response) => {
    console.log(request.url);
    response.writeHead(200, {
      'Access-Control-Allow-Origin': 'http://localhost:8080',
      'Access-Control-Allow-Credentials': 'true',
    //   'Content-Type': 'text/event-stream'
    });
    response.end('end')
    // static_directory.serve(request, response);

});
const stompServer = new StompServer({
    server: server,
    debug: console.log,
    path: '/stomp',
    protocol: 'sockjs',
    heartbeat: [20000, 20000]
});

console.log(' [*] Listening on 0.0.0.0:9999');
server.listen(9999, 'localhost');

stompServer.heartbeatOn(stompServer, 20000, true)

stompServer.subscribe("/subscribe", (msg, headers) => {
    var topic = headers.destination;
    console.log(`topic:${topic} messageType: ${typeof msg}`, msg, headers);
    stompServer.send('/subscribe', headers, `Hello from server! ${msg}`);
});

Modify the source code, print the parameters of the heartbeaton function and find that it is called elsewhere,which set serverside paramter to 'false'

 this.heartbeatOn = function (socket, interval, serverSide) {
    var self = this;
    console.log('###', socket, interval, serverSide)
    if (serverSide) {
      // Server takes responsibility for sending pings
      // Client should close connection on timeout
      socket.heartbeatClock = setInterval(function() {
        if(socket.readyState === 1) {
          self.conf.debug('PING');
          socket.send(BYTES.LF);
        }
      }, interval);

    } else {
      // Client takes responsibility for sending pings
      // Server should close connection on timeout
      socket.heartbeatTime = Date.now() + interval;
      socket.heartbeatClock = setInterval(function() {
        var diff = Date.now() - socket.heartbeatTime;
        if (diff > interval + self.conf.heartbeatErrorMargin) {
          self.conf.debug('HEALTH CHECK failed! Closing', diff, interval);
          socket.close();
        } else {
          self.conf.debug('HEALTH CHECK ok!', diff, interval);
          socket.heartbeatTime -= diff;
        }
      }, interval);
    }
  };

What the console prints is

### {
  on: [Function: on],
  send: [Function: send],
  close: [Function: close],
  sessionId: 'idxx'
} 20000 false

But I found the call in other places, which is:

function FrameHandler(stompServer) {
  this.CONNECT = function (socket, frame) {
    // setup heart-beat feature
    var rawHeartbeat = frame.headers['heart-beat'];
    var clientHeartbeat = [0, 0];
    if (rawHeartbeat) {
      clientHeartbeat = rawHeartbeat.split(',').map(function(x) { return parseInt(x); });
    }

    // default server heart-beat answer
    var serverHeartbeat = [0, 0];

    // check preferred heart-beat direction: client → server
    if (clientHeartbeat[0] > 0 && stompServer.conf.heartbeat[1] > 0) {
      serverHeartbeat[1] = Math.max(clientHeartbeat[0], stompServer.conf.heartbeat[1]);
      stompServer.heartbeatOn(socket, serverHeartbeat[1], true);
    }
    // check non-preferred heart-beat direction: server → client
    else if (clientHeartbeat[1] > 0 && stompServer.conf.heartbeat[0] > 0) {
      serverHeartbeat[0] = Math.max(clientHeartbeat[1], stompServer.conf.heartbeat[0]);
      stompServer.heartbeatOn(socket, serverHeartbeat[0], true);
    }

    if (stompServer.onClientConnected(socket, {
      heartbeat: clientHeartbeat,
      headers: frame.headers
    })) {
      ServerFrame.CONNECTED(socket, serverHeartbeat.join(','), stompServer.conf.serverName);
    } else {
      ServerFrame.ERROR(socket, 'CONNECTION ERROR', 'CONNECTION ERROR');
    }
  };

Besides modifying the source code, is there any other way to send a heartbeat to the client?