之前写过一篇使用laraval框架+node.js实现socket的文章,后台来了一个新的需求,每分钟定时上报连接数,需要node将链接发送到php,php每分钟上报一次;

我就想到了node这里把数据存到redis,然后php的定时任务每分钟从redis中取到连接数上报;

在取node写入redis的时候遇到了一些问题,在请教了node大拿之后解决了问题:

主要原因是:

redis客户端是个单例模式,发布订阅频道之后就不允许其它的操作(除(P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT之外,所以用作发布订阅之后,不能再用此实例写redis,所以就在重新实例化一个redis,做写入的处理;

 

 主要看代码如下:

// 常量
const port = 6001;
const evn = 'test';

// http server
let app = require('http').createServer((req, res) => {
    res.writeHead(200);
    res.end('');
});

// socket.io
let io = require('socket.io')(app);

// redis 连接
let Redis = require('ioredis');
let redisConfig = {};
if (evn === 'local') {
    redisConfig = {
        host: '127.0.0.1',
        port: '6379',
        password: null,
        db: 0
    };
} else if (evn === 'test') {
    redisConfig = {
        host: '47.94.*****0',
        port: '**',
        password: '******',
        db: 0
    };
}

const redis = new Redis(redisConfig);
const setRedis = new Redis(redisConfig);
// redis客户端是个单例模式,发布订阅频道之后就不允许其它的操作(除(P)SUBSCRIBE / (P)UNSUBSCRIBE / PING / QUIT之外)

redis.psubscribe('news.*', (err, count) => {
    // console.log('psubscribe-err', err);
    // console.log('psubscribe-count', count);
});
redis.on('pmessage', (subscrbed, channel, message) => {
    // console.log('pmessage-subscrbed', subscrbed);
    // console.log('pmessage-channel', channel);
    // console.log('pmessage-message', message);
    message = JSON.parse(message);
    console.log('[M]' + channel + ' Message :' + message.event, message.data);
    io.emit(channel + ':' + message.event, message.data);
});

const keys = {
    getRedisKey(key) {
        return `onlinereport:${key}`;
    },
};


let result = '';
const redisOption = {
    getRedisValue(key) {
        return setRedis.get(keys.getRedisKey(key), (err, res) => {
            if (err) {
                // console.log('err', err);
                return;
            }
            // console.log('res', res);
            result = res;
        });
    },
    setRedisValue(key, value, expired) {
        return setRedis.set(keys.getRedisKey(key), value, 'EX', expired);
    }
};

// socket.io 部分
const userList = [];
function countUser() {

    let userCount = [];


    for (var i in userList) {
        userCount[i] = userList[i].length;

    }
    return userCount;
}

function cookieToObject(data) {

    let new_Object = [];

    for (let i in data) {

        data[i] = data[i].split('=');

        new_Object[data[i][0]] = data[i][1];

    }

    return new_Object;

}


io.on('connection', (socket) => {

    socket.on('login', (user) => {

        if (userList[user.channel] === undefined) userList[user.channel] = [];

        if(user.openid.indexOf("admin") == -1){
            userList[user.channel].push(user.openid);
            io.emit(user.channel + ':UserChange', userList[user.channel]);
            let userCount = countUser();
            io.emit('user.count', userCount);
            console.log(user.channel)
            console.log(userList[user.channel].length)
            //当前在线人数写入缓存
            redisOption.setRedisValue(user.channel,userList[user.channel].length,86400)

        }

        console.log('[L] openid:' + user.openid + ' Login!');

    });


    socket.on('disconnect', (res) => {

        let cookie = socket.request.headers.cookie || '';
        if (cookie){
            let user = cookieToObject(cookie.split('; '));

            let openid = user['openid'] + "";

            if(openid.indexOf("admin") == -1){
                let index = userList[user['channel']].indexOf(user['openid'] + "");

                userList[user['channel']].splice(index, 1);

                io.emit(user.channel + ':UserChange', userList[user.channel]);

                let userCount = countUser();

                io.emit('user.count', userCount);

                redisOption.setRedisValue(user.channel,userList[user.channel].length,86400)
            }

            //当前在线人数写入缓存
            console.log('[L] openid:' + user['openid'] + ' Logout!');
        }
    });

    socket.on('user.count', () => {

        let userCount = countUser();

        io.emit('user.count', userCount);
        

    });

});


redis.psubscribe('*', (err, count) => {

});


app.listen(port, () => console.log('Server is running!'));
// 加上未捕获异常
process.on('uncaughtException', (err) => {
    console.log('uncaughtException', err);
    process.nextTick(() => process.exit(1));
});

 

 

posted on 2018-07-25 15:32  小良下山化了个缘  阅读(144)  评论(0编辑  收藏  举报