以前寫過一篇使用laraval框架+node.js實現socket的文章,後臺來了一個新的需求,每分鐘定時上報鏈接數,須要node將連接發送到php,php每分鐘上報一次;php
我就想到了node這裏把數據存到redis,而後php的定時任務每分鐘從redis中取到鏈接數上報;node
在取node寫入redis的時候遇到了一些問題,在請教了node大拿以後解決了問題:redis
主要緣由是:緩存
主要看代碼以下:cookie
// 常量 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)); });