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

来源:互联网 发布:常青藤软件64位 编辑:程序博客网 时间:2024/05/18 05:42

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