您的位置:首页 > Web前端 > Node.js

nodejs express+socket.io多线程原始实现

2017-07-28 15:35 323 查看

nodejs express+socket.io多线程原始实现

本文主要使用到express + socket.io 实现session共享,以及开启多线程。

session共享请参考上一片文章 http://blog.csdn.net/u012251421/article/details/76207034,里面详细介绍了如何使用express和socket.io 开启多线程。

下面介绍一下如何使用nodejs 内部的cluster实现多线程。如果是单纯的express,没有socket.io的情况是很好实现的,具体代码如下:

var app = require('../app'),
session = require('../session'),
cluster = require('cluster'),
net = require('net'),
numCPUs = require('os').cpus().length,
http = require('http'),
fs = require('fs'),
ServerPort = '80',
server = http.createServer(app),
config = JSON.parse(fs.readFileSync("./config.json")),
if (cluster.isMaster) {
console.log('Master is running');
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function (worker, code, signal) {
console.log('worker ${worker.process.pid} died');
});
} else {
server.listen(ServerPort);
server.on('error', onError);
server.on('listening', onListening);
}


使用上面的代码就可以实现单纯express多线程,上面使用到redis来实现session共享,代码如下:

var sess = require('express-session');
var RedisStore = require('connect-redis')(sess);
var redisConn = require('./routes/redis/redisConn');
// var session = sess({
//     secret: 'magustek.com',
//     name: 'magustek.com', //这里的name值得是cookie的name,默认cookie的name是:connect.sid
//     cookie: {maxAge: 30 * 60 * 1000}, //设置maxAge是30分钟,ession和相应的cookie失效过期
//     resave: false,
//     rolling: true,
//     saveUninitialized: true
// });

var session = sess({
secret: 'magustek.com',
store: new RedisStore({client: redisConn.Client, host: redisConn.IP, port: redisConn.PORT, ttl: 30 * 60, db: 15})
});
module.exports = session;


redisConn 内容:

/**
* Created by se7en on 2017/7/17.
*/

var redis = require('redis');
var fs = require('fs');

var logger = require('log4js').getLogger('system');
var dbConfig = JSON.parse(fs.readFileSync("./config.json"));

var IP = "192.168.2.64";
var PORT = 6379;
var USER = "root";
var PWD = "123456";

if (dbConfig && dbConfig.redis) {
var dbCon = dbConfig.redis;
if (dbCon.IP) {
IP = dbCon.IP;
}
if (dbCon.PORT) {
PORT = dbCon.PORT;
}
if (dbCon.USER) {
USER = dbCon.USER;
}
if (dbCon.PWD) {
PWD = dbCon.PWD;
}
}

var client = redis.createClient(PORT, IP);
client.on('error', function (error) {
client.quit();
logger.error('redis conn error:', error);
client = redis.createClient(PORT, IP);
});

var redisConn = {
name: 'redis',
PORT: PORT,
IP: IP,
Client: client
}

module.exports = redisConn;


使用以上就可以实现多线程的nodejs以及session共享了。

下面介绍一下express+socket.io实现多线程,具体代码如下:

var app = require('../app'),
session = require('../session'),
cluster = require('cluster'),
net = require('net'),
numCPUs = require('os').cpus().length,
http = require('http'),
fs = require('fs'),
api = require('../routes/api/apiV1'),
ServerPort = '80',
server = http.createServer(app),
io = require('socket.io').listen(server),
config = JSON.parse(fs.readFileSync("./config.json")),

if (config) {
if (config && config.server && config.server.PORT) {
ServerPort = config.server.PORT;
}
}
ServerPort = normalizePort(ServerPort);

if (cluster.isMaster) {
var workers = [];
var spawn = function (i) {
workers[i] = cluster.fork();
workers[i].on('exit', function (code, signal) {
console.log('respawning worker', i);
spawn(i);
});
};
for (var i = 0; i < numCPUs; i++) {
spawn(i);
}
var worker_index = function (ip, len) {
var s = '';
for (var i = 0, _len = ip.length; i < _len; i++) {
if (!isNaN(ip[i])) {
s += ip[i];
}
}
return Number(s) % len;
};
var server = net.createServer({pauseOnConnect: true}, function (connection) {
var worker = workers[worker_index(connection.remoteAddress, numCPUs)];
worker.send('sticky-session:connection', connection);
}).listen(ServerPort);
} else {
api.init(io);
server.listen(0);
process.on('message', function (message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
server.emit('connection', connection);
connection.resume();
});
}

function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}


可以看出和单纯的express相比主要修改了cluster.isMaster里面的处理逻辑,不同系统下处理逻辑不太一样,不过可以参考以上的实现。

参考文章:

https://github.com/elad/node-cluster-socket.io

https://my.oschina.net/swingcoder/blog/527648
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息