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

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

SUBSCRIBE无法处理。连接已经关闭。

当用户刷新页面时,socket重新连接,我的sub RedisClient对象会抛出此异常。这个事件又会导致我的server.js也崩溃。当我在io.sockets.on连接中注释掉所有的sub和pub对象时,socket重新连接没有任何异常,并且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堆栈跟踪:
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 对象无法处理这些 socket 断开连接。在任何子订阅(sub)和发布(pub)对象周围添加 try-catch 块(例如:try { sub.subscribe("chatbox"); } 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个回答

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) {
  ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接