ZeroMQ:如何从订阅者通知发布者

时间:2015-07-28 10:14:19

标签: node.js zeromq

我使用 PUB/SUB ZeroMQ模式。

系统包括Web服务器( Pub lisher),集群TCP服务器( Sub scribers)和外部应用程序(客户端,连接到TCP服务器)。

大量外部客户端连接到每个TCP服务器。每个外部客户端都有唯一的peerId我在 Pub lisher中用作主题。出于某些管理目的,我将消息发送到TCP服务器(如删除对等,更改等)。但我还需要从TCP服务器向Web服务器发送消息(连接,断开连接,错误)。我没找到正确的方法怎么做。任何人都可以建议如何正确地做到这一点?

更新1

看起来使用 ROUTER / DEALER 模式是最方便的。

关于脚本的一些评论。

外部客户端连接到tcp服务器(集群)并在由唯一peerId缓存的tcp服务器端tcp套接字上发送唯一peerId。然后tcp服务器通过ZeroMQ套接字向Web服务器发送peerId消息。 Web服务器通过envelope缓存peerId。每隔n毫秒Web服务器将消息发送到随机对等方(生成'peerId')。 TCP Server收到这些消息,从缓存中获取正确的tcp套接字并将其发送给客户端。客户端计算消息计数,每n毫秒将其发送到TCP服务器,TCP服务器通过ZeroMQ套接字将计数发送到WEB服务器。在Web服务器上,每个n毫秒的已发送和已接收消息的数量都会打印在控制台上。

测试服务器部分的js脚本:

var cluster = require('cluster'),
    zmq = require('zmq'),
    net = require('net'),
    zmqport = 'tcp://127.0.0.1:12345';

var count = 10;
var countPeers = 10000;
var interval = 1;

if (cluster.isMaster) {

  for (var i = 0; i < count; i++) cluster.fork({
    TCP_SERVER: 1
  });
  
  cluster.fork({
    WEB_SERVER: 1
  });
  
  cluster.on('death', function (worker) {
    console.log('worker ' + worker.pid + ' died');
  });
} else {
  
  if (process.env.TCP_SERVER) {
    
    var sockets = Object.create(null);
    var socket = zmq.socket('dealer');
    
    socket.identity = 'process-' + process.pid;
    socket.connect(zmqport);
    
    socket.on('message', function (peerIdBuffer) {
      
      var peerId = peerIdBuffer.toString();
      if (typeof sockets[peerId] !== 'undefined') {
        
        var buffer = new Buffer(4);
        buffer.writeUInt32BE(1, 0);
        sockets[peerId].write(buffer);
      }
    });
    
    var server = net.createServer(function (tcpsocket) {
      
      tcpsocket.on('data', function (data) {
        if (!tcpsocket.peerId) {
          var peerId = data.toString();
          sockets[peerId] = tcpsocket;
          tcpsocket.peerId = peerId;
          return socket.send(['id', data]);
        }
        return socket.send(['count', data]);
      });      
    });
    
    server.listen('13333', '0.0.0.0');
  } else { 
    
    var countMessagesSended = 0;
    var countMessagesReceived = 0;
    
    var socket = zmq.socket('router');
    var clients = Object.create(null);
    
    socket.bind(zmqport, function (err) {
      if (err) throw err;
      
      setInterval(function () {
        for (var i = 0; i < countPeers; i++) {
          var topic = Math.floor(Math.random() * countPeers) + '-peer';
          
          if (typeof clients[topic] !== 'undefined') {
            countMessagesSended++;
            socket.send([clients[topic], topic]);
          }
        }
      }, interval);
    });
    
    socket.on('message', function (envelope, messageId, data) {
      switch (messageId.toString()) {
        case "id":
          clients[data.toString()] = envelope.toString();
          break;
        case "count":
          countMessagesReceived += data.readUInt32BE(0);
          break;
      }
    });
    
    setInterval(function () {
      console.log('%s messages have been sended, %s - received', countMessagesSended, countMessagesReceived);
      countMessagesSended = 0;
      countMessagesReceived = 0;
    }, 5000);
  }
}

为客户测试js脚本:

var cluster = require('cluster'),
    net = require('net');

var count = 10;

if (cluster.isMaster) {
  for (var i = 0; i < count; i++) cluster.fork({
    CLUSTER: i
  });
  
  cluster.on('death', function (worker) {
    console.log('worker ' + worker.pid + ' died');
  });
} else {
  var clientspernode = 1000;
  
  var offset = parseInt(process.env.CLUSTER, 10);

  for (var j = (offset) * clientspernode; j < (offset + 1) * clientspernode; j++) {
    (function (j) {
      var countMessages = 0;

      var client = net.connect({
        port: 13333,
        host: '127.0.0.1' 
      }, function () {
        client.write(j + '-peer');
      });
      client.on('data', function (buffer) {
        countMessages += Math.ceil(buffer.length / 8);
      });
      client.on('error', function () {
      });

      setInterval(function () {
        var buf = new Buffer(4);
        buf.writeUInt32BE(countMessages, 0);
        client.write(buf);
        countMessages = 0;
      }, 5000);
    })(j);
  }

 
}

0 个答案:

没有答案