Bonjour à tous,

je cherche a faire fonctionner des websocket en cluster.
à l'heure actuelle mon programme nodejs a gagner énormément en performance grace à ça.

le problème maintenant est que je n'arrive pas à faire communiquer les différents processuse entre eux.
ceci ne pause aucuns problèmes apparents lorsque j'effectue qu'une seule requête.
Mais à chaque fois qu'il y a requète, il y a possibilitée de créer un nouveau socket sans que le socket du serveur ne se ferme.

les questions :
  • il y a t'il une possibilitée de relier tous les serveurs websocket (socket.io par exemple) à travers un processus maître tout en concervant donc tous mes serveurs http/https simultanément.
  • Sinon dois me concentrer sur un seul serveur http/https et appliquer des worker à celui... (bottleneck ????)

je m'en remets à vos avis

j'ai testé

  • redis

fichier maître:

let cluster = require('cluster');
let os = require('os');
let cpu = os.cpus();
let cfg = require('./cfg.json');
let sqp = require('./lib/sql_profile');

function server_start() {
    console.log('mcm: server is starting');
    mysql_init();
    function mysql_init(){
        //mysql init

        let sql = sqp.normal
        let basic_sql = sqp.basic
        let mysql = require('mysql')

        var con = mysql.createConnection(sql)

        con.connect((err, res) => {
            if (err) {
                con.destroy();
                setTimeout(() => {
                    con.end()
                    create_db()
                }, 200);
            } else {
                console.log('mcm: controling mysql table')
                setTimeout(() => {
                    controle_tables()
                }, 100);
            }
        })
        function create_db() {
            con = mysql.createConnection(basic_sql)
            con.connect((err, res) => {
                if (err) {
                    console.log("mcm: couldn't connect to mysql server (make sure that your mysql server is on or good configured)")
                } else {
                    console.log("mcm: creating mysql database")
                    con.query('CREATE DATABASE '+cfg.mysql.database+' CHARACTER SET utf8 COLLATE utf8_bin', (err, res) => {
                        if (err) {
                            console.log("mcm: unable to create the database")
                            return process.exit(0);
                        } else {
                            console.log("mcm: database created !!")
                            console.log('mcm: installing mysql table')
                            con.destroy()
                            con = mysql.createConnection(sql)
                            controle_tables()
                        }
                    });
                }
            });
        }

        function controle_tables() {

            let tb_list = ["mcm_user", "mcm_post", "mcm_post_answer", "mcm_forum", "mcm_forum_answer"];

            let crt_set = {

                mcm_user: "create table if not exists mcm_user(id INT(20) PRIMARY KEY AUTO_INCREMENT, "+
                    "account VARCHAR(20), password VARCHAR(255) NOT NULL, describ VARCHAR(255) NULL, group_list TEXT NULL, "+
                    "public_name VARCHAR(20) NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, last_login DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "+
                    "power_level INT DEFAULT '0', suspend ENUM('0','1') NOT NULL DEFAULT '0', user_status ENUM('online','offline','away') NOT NULL DEFAULT 'offline',"+
                    "mail VARCHAR(36), is_admin ENUM('TRUE','FALSE') NOT NULL DEFAULT 'FALSE')",

                mcm_post: "create table if not exists mcm_post(id INT(40)PRIMARY KEY AUTO_INCREMENT, "+
                    "autor VARCHAR(255) NOT NULL, reaction TEXT NULL, tag VARCHAR(255) NULL DEFAULT 'random',"+
                    "content TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"+
                    ")",

                mcm_post_answer: "create table if not exists mcm_post_comment(id INT(40)PRIMARY KEY AUTO_INCREMENT, "+
                    "post_id INT(40) NOT NULL, autor VARCHAR(255) NOT NULL, reaction TEXT NULL, "+
                    "content TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"+
                    ")",
                mcm_forum: "create table if not exists mcm_forum(id INT(40)PRIMARY KEY AUTO_INCREMENT, "+
                    "category VARCHAR(255) NOT NULL DEFAULT 'uncategorised', topic VARCHAR(255) NOT NULL DEFAULT 'default',"+
                    "autor VARCHAR(255) NOT NULL, reaction TEXT NULL, modified DATETIME NULL, "+
                    "subject VARCHAR(255) NULL, content TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP"+
                    ")",
                mcm_forum_answer: "create table if not exists mcm_forum_comment(id INT(40)PRIMARY KEY AUTO_INCREMENT, "+
                    "subject_id INT(40) NOT NULL, autor VARCHAR(255) NOT NULL, reaction TEXT NULL, "+
                    "content TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, modified DATETIME NULL"+
                    ")"
            }

            var i = 0;
            tb_list.forEach(table => {
                con.query(crt_set[table], (err, res) => {
                    if (err) {
                        console.log(err);
                        return process.exit(0);
                    } else {
                        console.log('mcm: '+table.replace('mcm_', '')+' ready !');
                        i++;
                        if (i == tb_list.length) {
                            console.log('mcm: mysql database are ready to be used! ');
                            find_user_admin();
                        }
                    }
                });

            });

            function find_user_admin() {
                var rows = []
                con.query('SELECT * FROM mcm_user WHERE account = ? AND password = ?', [cfg.admin.account, cfg.admin.password])
                .on('result', (row, any) => {
                    rows.push(row)
                })
                .on('end', () => {
                    if (rows.length === 0) {
                        con.query('INSERT INTO mcm_user (account, password, public_name, mail, is_admin)'+
                            ' VALUES (?,?,?,?,?)', [cfg.admin.account, cfg.admin.password,
                                cfg.admin.public_name, cfg.admin.mail, 'TRUE'])
                    }
                    enable_threads();
                })
            }

        }
    }

}

function enable_threads() {
    for (let i = 0; i < cpu.length; i++) {
        cluster.fork()
    }
    cluster.on('exit', (worker, code, signal) => {
        console.log('worker '+ worker.process.pid +' terminated');
    });
}

if (cluster.isMaster) {

    //single thread socket
    let io = require('socket.io')()
    io.on('connection', (socket)=>{
        console.log('new');

    })
    //begin server
    server_start()

} else {
    require('./cluster.js');
}

cluster :

let http = require('http')
let https = require('https')
let url = require('url')
let fs = require('fs')
let cfg = require('./cfg.json')
let ext = require('path')
let app = require('express')()
let session = require('express-session')
let MySqlStore = require('express-mysql-session')(session);
let bodyParser = require('body-parser')
let cookieParser = require('cookie-parser')

    // body-parser
    var url_encoder = bodyParser.urlencoded({ extended: false })
    var jsonParser = bodyParser.json()

    // mysql-session-setup
    var store_opt = {
        host: cfg.mysql.server,
        port: cfg.mysql.port,
        user: cfg.mysql.user,
        password: cfg.mysql.pass,
        database: cfg.mysql.database,
        clearExpired: true,
        checkExpirationInterval: 1000 * 60 * 30,
        endConnectionOnClose: true,
        charset: 'utf8mb4_bin',
        schema: {
            tableName: 'mcm_session',
            columnNames: {
                session_id: 'session_id',
                expires: 'expires',
                data: 'data'
            }
        }
    }
    let store = new MySqlStore(store_opt)

    //cookies
    app.use(cookieParser('lorem_pixeview'))

    //session
    app.set('trust-proxy', 1)
    app.use(session({
        name: 'session',
        secret: 'lorem_pixeview',
        store: store,
        resave: false,
        saveUninitialized: false,
        cookie: {
            maxAge: 1000*60*60*24*30,
            sameSite: 'Lax',
            secure: true
        }
    }))

    function session_update(req, res) {
        var session = req.session;
        session.cookie.expires = new Date(Date.now() + (1000*60*60*24*30));
    }

    function cookie_update(req, res) {
        var session = req.session
        var sessionparam = req.session.cookie
        sessionparam.sameSite = 'Lax'
        var cookie = req.cookies["user-param"]
        if (!cookie) {
            res.cookie('user-param', {account:"",password:"",connected:false}, sessionparam)
        }
        if (session.connected == true) {
            res.cookie('user-param', {account:session.username ,password:session.password ,connected:true}, sessionparam)
        }

    }

    // http redirect
    http.createServer((req, res) => {
        path = url.parse(req.url).pathname;
        host = req.headers.host;
        res.writeHead(301, {Location: 'https://'+host+path })
        res.end()
    }).listen(80)

    //https
    let ssl_opt = {
        key: fs.readFileSync('./lib/ssl/key.pem'),
        cert: fs.readFileSync('./lib/ssl/cert.pem')
    }

    let serv = https.createServer(ssl_opt, app)
    var _404 = '<h1> FILE NOT FOUND</h1>'
    var _403 = '<h1> FORBBIDEN ACCESS</h1>'

    app.get('/', (req, res) => {
        var cookie = req.cookies['user-param']
        if (!req.session.connected && cookie) {
            if (cookie.connected != false) {
                require('./lib/pages/session').connect(req, res, data = {account:cookie.account, password:cookie.password})
                return false;
            }
        } else {
            session_update(req, res)
            cookie_update(req, res)
        }

        //initial
            fs.readFile('index.html', 'utf-8' ,(err, data) => {
                if (err) {
                    res.writeHead(404)
                    res.send(_404)
                } else {
                    if (req.session.connected == true) {
                        data = data.replace('<body class="s-showpage">', '<body class="s-left-navigation">')
                    } else if (req.session.badlogin) {
                        delete req.session.badlogin
                        data = data.replace('<body class="s-showpage">', '<body class="s-showpage wrong-password">')
                    }
                    res.end(data)
                }
            })

    })

    app.get('/*', (req, res) => {
        var file = req.url.replace('/','')
        if (file.match(/lib\/.+|cfg\.json|package.+|node_modules\/.+/g)) {
            res.writeHead(403)
            res.end(_403)
            return false;
        }
        fs.readFile(file, (err, data) => {
            if (err) {
                res.writeHead(404)
                res.end(_404)
            } else {
                var fmt = ext.extname(file);
                switch (fmt) {
                    // exec files
                    case '.css':
                        res.writeHead(200, {'Content-Type':'text/css'})
                        break;
                    case '.js':
                        res.writeHead(200, {'Content-Type':'application/javascript'})
                        break;
                    case '.json':
                        res.writeHead(200, {'Content-Type':'application/json'})
                        break;
                    case '.html':
                        res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'})
                        break;
                    case '.xml':
                        res.writeHead(200, {'Content-Type':'application/xml'})
                        break;
                    // archives
                    case '.zip':
                        res.writeHead(200, {'Content-Type':'application/zip'})
                        break;
                    case '.rar':
                        res.writeHead(200, {'Content-Type':'application/x-rar-compressed'})
                        break;
                    // image-icons
                    case '.ico':
                        res.writeHead(200, {'Content-Type':'image/x-icon'})
                        break;
                    case '.jpg' || '.jpeg':
                        res.writeHead(200, {'Content-Type':'image/jpeg'})
                        break;
                    case '.png':
                        res.writeHead(200, {'Content-Type':'image/png'})
                        break;
                    case '.gif':
                        res.writeHead(200, {'Content-Type':'image/gif'})
                        break;
                    case '.svg':
                        res.writeHead(200, {'Content-type':'image/svg+xml'})
                        break;
                    // media
                    case '.aac':
                        res.writeHead(200, {'Content-type':'audio/aac'})
                        break;
                    case '.mid' || '.midi':
                        res.writeHead(200, {'Content-type':'audio/midi'})
                        break;
                    case '.rtf':
                        res.writeHead(200, {'Content-type':'application/rtf'})
                        break;
                    case '.ttf':
                        res.writeHead(200, {'Content-type':'font/ttf'})
                        break;
                    case '.avi':
                        res.writeHead(200, {'Content-type':'video/x-msvideo'})
                        break;
                    case '.mpeg':
                        res.writeHead(200, {'Content-type':'video/mpeg'})
                        break;
                    default:
                        res.writeHead(200)
                        break;
                }
                res.end(data);
            }
        });
    })

    app.post('/', (req, res) => {
        session_update(req, res)
        cookie_update(req, res)
        var pages = ['post']
        var data = "";
        req.on('data', chunk => {
            data += chunk
        })
        req.on('end', () => {
            var mpage = ""
            var arr = pages.forEach(el => {
                mpage += " |"+el+"| "
            })
            var filter = data.match('/'+mpage+'/')
            if (filter) {
                var getpage = pages.indexOf(filter[0])
            }
            if (getpage >= 0) {
                require('./lib/pages/'+filter+'.js')(res, data.match(/{.+}/g)[0])
            }
        })
    })

    app.post('/login', url_encoder ,(req, res) => {
        require('./lib/pages/session').connect(req, res, req.body)
    })

    app.post('/logout', (req, res) => {
        req.session.destroy()
        res.cookie('user-param', '', {maxAge:0})
        res.writeHead(200, {
            'Content-type':'text/plain'
        })
        res.end()
    })

    serv.listen(443);

Aucune réponse