Socket.IO - Redis:SUBSCRIBE无法处理。连接已关闭

时间:2017-01-15 23:07:25

标签: node.js redis socket.io

我有一个简单的Redis - Socket.IO聊天应用程序,当用户点击F5或尝试刷新页面时会抛出以下(redis)异常:

  

不能处理SUBSCRIBE。连接已经关闭。

当用户刷新页面时,套接字重新连接,我的子RedisClient对象抛出此异常。此事件反过来导致我的server.js崩溃。在io.sockets.on连接中注释掉所有sub和pub对象时,套接字将重新连接而没有任何异常,并且server.js继续运行。

我的server.js

var socket = require('socket.io');
var express = require('express');
var http = require('http');
var redis = require('redis');

var app = express();
var server = http.createServer(app);
var io = socket.listen(server);

var pub = redis.createClient();
var sub = redis.createClient();

app.use(express.static(__dirname));

io.sockets.on('connection', function (client) {

    sub.subscribe("chatbox");

    sub.on("message", function (channel, message) {
        console.log("Message received, publishing...");
        client.send(message);
    });

    client.on("message", function (msg) {
        console.log(msg);
        pub.publish("chatbox", msg.message);
    });

    client.on('disconnect', function () {
        sub.quit();
        pub.publish("chatbox", "User: " + client.id + "  is disconnected");
    });

    client.on("error", function (err) {
        console.log("Error " + err);
    });
});

server.listen(8888);

(简化)html部分:

$(document).ready(function() {

        var username ='Someone';
        var socket = new io.connect('http://localhost:8888');           
        var msg = {type:'setUsername',user:username};

        socket.json.send(msg);

        socket.on('connect', function() {
            console.log("Connected: " + Date());
        });

        $(window).on('beforeunload', function(){
            socket.close();
        })

        //...

node.js stacktrace:

AbortError
at handle_offline_command (c:\xampp\htdocs\chatbox\node_modules\redis\index.js:839:15)
at RedisClient.internal_send_command (c:\xampp\htdocs\chatbox\node_modules\redis\index.js:873:9)
at RedisClient.subscribe (c:\xampp\htdocs\chatbox\node_modules\redis\lib\individualCommands.js:419:17)
at Namespace.<anonymous> (c:\xampp\htdocs\chatbox\nodeServer4.js:17:6)
at emitOne (events.js:96:13)
at Namespace.emit (events.js:188:7)
at Namespace.emit (c:\xampp\htdocs\chatbox\node_modules\socket.io\lib\namespace.js:209:10)
at c:\xampp\htdocs\chatbox\node_modules\socket.io\lib\namespace.js:177:14
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)

似乎RedisClient对象无法处理这些套接字断开连接。在任何sub,pub对象(例如try { sub.subscribe("chatbox"); } catch { })周围添加try catch也没有帮助。

修改

添加以下行会使server.js保持活动状态,但仍会抛出异常,无法订阅,因此不会发布:

sub.on("error", function (err) {
    console.log("Error " + err);
});

pub.on("error", function (err) {
    console.log("Error " + err);
});

Error AbortError: SUBSCRIBE can't be processed. The connection is already closed.

1 个答案:

答案 0 :(得分:1)

sub.subscribe(“chatbox”)应该在io连接的范围之外。只需要一个订阅。

var pub = redis.createClient();
var sub = redis.createClient();
sub.subscribe("chatbox");

app.use(express.static(__dirname));

io.sockets.on('connection', function (client) {
  sub.on("message", function (channel, message) {
  ...