Node.js+Socket.io訊息中心實施之六 訊息中心的實現(4)
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- DDD實戰分享-訊息中心
- 聊聊訊息中心的設計與實現邏輯
- 仿微博訊息中心的系統設計與實現
- SpringCloud 2020.0.4 系列之 Stream 訊息廣播 與 訊息分組 的實現SpringGCCloud
- workerman 實現訊息推送
- 如何優雅的實現訊息通訊?
- PHP基於Redis訊息佇列實現的訊息推送的方法PHPRedis佇列
- Flutter websocket 實現訊息推送FlutterWeb
- Redis實現訊息佇列Redis佇列
- SpringCloud 2020.0.4 系列之 Stream 延遲訊息 的實現SpringGCCloud
- paho實現MQTTClient釋出訊息MQQTclient
- 使用 NSProxy 實現訊息轉發
- Redis 使用 List 實現訊息佇列能保證訊息可靠麼?Redis佇列
- 億級訊息中心架構方案概述【原創】架構
- Redis 學習筆記(六)Redis 如何實現訊息佇列Redis筆記佇列
- Fluter訊息機制之微任務實現原理
- js訊息訂閱和釋出實現元件之間通訊JS元件
- 延遲訊息的五種實現方案
- 造輪子之訊息實時推送
- WIN10如何設定通知中心不顯示訊息 WIN10通知中心不顯示訊息設定方法Win10
- 利用localstorage實現本地訊息快取快取
- 實現rabbitmq訊息重新投遞方案MQ
- C# 使用SignalR實現訊息通知C#SignalR
- Qt實現系統托盤訊息QT
- QStyledItemDelegate 和QTreeView實現滑鼠hover訊息QTView
- 使用Spring Boot實現訊息佇列Spring Boot佇列
- Redis實現訊息釋出訂閱Redis
- 延時訊息常見實現方案
- Knative 實戰:基於 Kafka 實現訊息推送Kafka
- RabbitMQ實戰:理解訊息通訊MQ
- 實時訊息推送整理
- 物聯網:實現sIoT配置並實現sIoT上mqtt訊息的通訊MQQT
- RestCloud MQ訊息整合平臺,實現訊息自動記錄及重發RESTCloudMQ
- 基於公共信箱的全量訊息實現
- RabbitMQ實現延時訊息的兩種方法MQ
- 實現mind+下Easy IoT上mqtt訊息的通訊。MQQT
- 阿里雲訊息佇列 Kafka-訊息檢索實踐阿里佇列Kafka
- IM撤回訊息-iOS客戶端實現iOS客戶端
- 基於 Hyperf 實現 RabbitMQ + WebSocket 訊息推送MQWeb