Node.js+Socket.io訊息中心實施之六 訊息中心的實現(4)

百聯達發表於2014-07-14
Server.js  服務類

1. 建立叢集 cluster是一個nodejs內建的模組,用於nodejs多核處理。cluster模組,可以幫助我們簡化多程式並行化程式的開發難度,輕鬆構建一個用於負載均衡的叢集。

var cluster = require('cluster');
var http = require("http");
var url  = require("url");
var logger = require("./logger");
var redis = require("./redis");
var RedisStore = require('/usr/local/lib/node_modules/socket.io/lib/stores/redis');
var io = require("/usr/local/lib/node_modules/socket.io");
var numCpus = require('os').cpus().length;
var server;
var workers = {};


function start(route,handle) {
 
   //Http 請求響應
     function onRequest(request,response)
  {
  
  var pathname=url.parse(request.url).pathname;
  logger.info("Request for"+pathname+" received.");
  route(handle,pathname,response,request);
  
        }
 
   //叢集配置
    if(cluster.isMaster)
    {
  logger.info("[master] start master.....cpus:"+numCpus);
     //初始化:開啟與CPU數相同的工作程式
     for(var i=0;i
      {
       var worker=cluster.fork();
       workers[worker.process.pid]=worker;
      }

      //記錄工作程式的關閉過程
      cluster.on('exit',function(worker, code, signal){
        logger.info('Worker ' + worker.process.pid + ' died.');
        });

      //當一個工作程式結束時,重啟工作程式
       cluster.on('death',function(worker){
    logger.info('Worker ' + worker.process.pid + ' death.');
        delete workers[worker.process.pid];
        worker=cluster.fork();
        workers[worker.process.pid]=worker;
        });
       //監聽worker的啟動過程
       cluster.on('listening',function(worker,address){
        logger.info('A worker with #'+worker.process.pid+' is now connected to '+address.address + ':'+address.port);
        });
     
    }
    else if(cluster.isWorker)
    {
    
        var pub=redis.createClient();
        var sub=redis.createClient();
        var client=redis.createClient();
  //監聽http埠
        server=http.createServer(onRequest).listen(8080);
  io = io.listen(server,
  {
          'store' : new RedisStore({
          redisPub : pub,
          redisSub : sub,
          redisClient : client}),
   });
 
   
2.服務端引數設定

    //設定socket io日誌級別
     io.set('log level',2);
  //設定客戶端應該在多少時間內接收到一個心跳訊號
  io.set('heartbeat timeout',20);
  //設定伺服器端每隔多上時間應該發一個心跳訊號
  io.set('heartbeat interval',10);
     //設定客戶端在超過多少時間之後進行重新連線
  io.set('close timeout',20);

  io.set('transports', ['websocket']);
  //io.set('force new connection',true);
  io.set('max reconnection attempts',2);
     io.set('reconnection delay',500);
   io.set('reconnect',false);
  //io.set('polling duration',10);


3.訊息監聽


 /*
   *監聽connection
   */
   io.sockets.on('connection',function(socket){
               logger.info("Connection "+socket.id+" accepted.");

                     //使用者資訊註冊
          socket.on('bind',function(userInfo){
                   logger.info("Received message:"+userInfo+"-- from client "+socket.id);
       redis.bind(socket,userInfo);
                   });
                     
         //訂閱話題
                      socket.on('sub',function(msg,fn){
                   logger.info("sub message:"+msg+"-- from client "+socket.id);
       redis.sub(socket,msg,fn);
                   });


           //取消訂閱話題
                      socket.on('unsub',function(msg,fn){
                   logger.info("unsub message:"+msg+"-- from client "+socket.id);
       redis.unsub(socket,msg,fn);
                   });

                     //向指定人員傳送訊息
                      socket.on('sendMsgToUser',function(msg,fn){
                   logger.info("Received message:"+msg+"-- from client "+socket.id);
       redis.sendMessageToUser(io,msg,fn);
                   });
      //向指定房間傳送訊息
                      socket.on('sendMsgToRoom',function(msg,fn){
                   logger.info("Received room message:"+msg+"-- from client "+socket.id);
       redis.sendMsgToRoom(socket,msg,fn);
                   });
        //向指定房間傳送訊息P2P
                      socket.on('sendMsgToRoomP2P',function(msg,fn){
                   logger.info("Received room message:"+msg+"-- from client "+socket.id);
       redis.sendMsgToRoomP2P(io,msg,fn);
                   });
       //訊息接收成功回撥函式
                      socket.on('clear',function(msg){
                   logger.info("Received room callback message:"+msg+"-- from client "+socket.id);
       redis.clear(socket,msg);
                   });
      //向所有人傳送訊息
          socket.on('sendMsgToAll',function(msg,fn){
                   logger.info("Received all message:"+msg+"-- from client "+socket.id);
       redis.sendMsgToAll(io,msg,fn);
                   });

                      //監聽connect斷開連線
       socket.on('disconnect',function(){
       logger.info("Connection "+socket.id+" terminated.");
       }); 

  });
}

  //當master關閉時,同時關閉所有worker
     process.on('SIGTERM',function()
     {
      for(var pid in workers)
      {
    console.info('kill worker pid:'+pid);
       process.kill(pid);
      }
   
      process.exit(0);
     }
     );
}

exports.start = start;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-1218482/,如需轉載,請註明出處,否則將追究法律責任。

相關文章