Ошибка: Соединение в абонентском режиме, можно использовать только абонентские команды

Я обнаружил ошибку при отправке данных сообщения в Redis. Пожалуйста, дайте мне некоторые рекомендации об ошибке. почему это происходит? Я хотел бы хранить данные чата в Redis, используя nodejs.

server.js (сервер):

/*
 * -------------------
 * Express
 * -------------------
 */
var app = require('express')(),
        session = require("express-session");

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Headers", "Content-Type");
    res.header("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
    next();
});
app.set('host', "localhost");
app.set('port', 8080); //process.env.PORT

/*
 * -------------------
 * Socket Connections
 * -------------------
 */
var server = require('http').createServer(app);
var io = require('socket.io')(server);
server.listen(app.get("port"), app.get("host"), function () {
    console.log("Server up and running...");
});
io.set('log level', 3);

/*
 * -------------------
 * Redis 
 * -------------------
 */
var redis = require("redis");
/*
 *  Sender
 */
var publisher = redis.createClient();
/*
 * Receiver
 */
var subscriber = redis.createClient();
/*
 * -------------------
 * Mysql
 * -------------------
 */
/*var mysql = require("mysql");
 var connection = mysql.createConnection({
 host: "localhost",
 user: "root",
 password: "password",
 database: "w"
 });
 connection.connect();*/

/*
 * -------------------
 * functions
 * -------------------
 */
function subscribeMessage(_subscriber) {
    subscriber.subscribe(_subscriber);
    subscriber.on("message", function (channel, message) {
        console.log("redis connection message:" + message);
    });
}
function pushToRedis(data) {
    subscriber.lpush('wchannel', data);
}

/*
 * -------------------
 * Redis Subscriber
 * -------------------
 */
subscriber.subscribe("wchannel");
subscribeMessage("wchannel");
/*subscriber.on("message", function (channel, message) {
 //console.log("client channel recieve from channel : %s, the message : %s", channel, message);
 });*/

/* 
 * -------------------
 * Socket
 * -------------------
 */
io.sockets.on('connection', function (socket) {    
    console.log("app port :: " + app.get("port"));
    socket.on('connection', function (data) {
        console.log('Server running on *:' + app.get('port'));
    });
    //socket.emit("connected", {msg: ""});        
    socket.on("chat", function (data) {
        pushToRedis(data.msg);
        //subscriber.ltrim('messages', 0, 99);
        socket.emit("publishMessage", {msg: data.msg});
    });
    socket.on('disconnect', function () {
    });
});

script.js (клиент):

$(function () {
    var socket = io.connect("http://localhost:8080/");
    /*
     * -------------------
     * Methods
     * -------------------
     */
    $.fn.clearAndFocus = function () {
        $("#txtMessage").val("").focus();
    };
    $.fn.sendMessageToServer = function () {
        socket.emit("chat", {msg: $("#txtMessage").val()});
        $.fn.clearAndFocus();
    };
    $.fn.clearAndFocus();
    /*
     * -------------------
     * Events
     * -------------------
     */
    $("#btnSend").on("click", function () {
        $.fn.sendMessageToServer();
    });
    $("#txtMessage").on("keyup", function (e) {
        if (e.keyCode === 13) {
            $.fn.sendMessageToServer();
            $.fn.clearAndFocus();
        }
    });
    /*
     * -------------------
     * Socket Events
     * -------------------
     */
    socket.on('connect', function () {
        console.log("w client is connected");
    });
    socket.on("publishMessage", function (data) {
        console.log(data.msg);
        $(".chatlog").append("\n\
                        <div class=\"chat-row\">\n\
                        <div class=\"chat-text\">" + data.msg + "\n\
                        </div>");

    });
    socket.on('disconnect', function () {
    });
});

консоль.лог:

root@wk11:/var/www/html/wchat/nodejs# nodejs server.js
Option log level is not valid. Please refer to the README.
Server up and running...
redis connection message:{"msg":"56151810ceff6 is connecting..."}
app port :: 8080
chat emtis
Missing error handler on `socket`.
Error: Connection in subscriber mode, only subscriber commands may be used
    at RedisClient.send_command (/var/www/html/wchat/nodejs/node_modules/redis/index.js:751:15)
    at RedisClient.(anonymous function) (/var/www/html/wchat/nodejs/node_modules/redis/index.js:891:21)
    at pushToRedis (/var/www/html/wchat/nodejs/server.js:71:16)
    at Socket.<anonymous> (/var/www/html/wchat/nodejs/server.js:99:9)
    at Socket.emit (events.js:95:17)
    at Socket.onevent (/var/www/html/wchat/nodejs/node_modules/socket.io/lib/socket.js:330:8)
    at Socket.onpacket (/var/www/html/wchat/nodejs/node_modules/socket.io/lib/socket.js:290:12)
    at Client.ondecoded (/var/www/html/wchat/nodejs/node_modules/socket.io/lib/client.js:193:14)
    at Decoder.Emitter.emit (/var/www/html/wchat/nodejs/node_modules/component-emitter/index.js:134:20)
    at Decoder.add (/var/www/html/wchat/nodejs/node_modules/socket.io-parser/index.js:247:12)

person Dipak    schedule 07.10.2015    source источник


Ответы (2)


Я создал новый дочерний объект подписчика в socket.io, и он решит мою проблему, как описано ниже. Поскольку родительский объект подписчика недоступен в io.sockets.on(), а также мне пришлось создать еще один дочерний объект для подписчика.

/*
 *  Sender
 */
var publisher = redis.createClient();
/*
 * Receiver
 */
var subscriber = redis.createClient();

/* 
 * -------------------
 * Socket
 * -------------------
 */
io.sockets.on('connection', function (socket) {
    var _subscriber = redis.createClient();
    //console.log("app port :: " + app.get("port"));    
    console.log("Session: %j", sessionHandler);
    //console.log(JSON.stringify(sessionHandler, null, 4));
    socket.on('connection', function (data) {
        console.log('Server running on *:' + app.get('port'));
    });
    socket.on('disconnect', function () {
    });
});
person Dipak    schedule 08.10.2015

Согласно документации Redis:

Как только клиент входит в состояние подписки, он не должен выдавать никаких других команд, кроме дополнительных команд SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE и PUNSUBSCRIBE.

Ссылка: http://redis.io/commands/subscribe

Чтобы отправить команду lpush, вам нужно создать еще один клиент Redis, который не находится в состоянии подписки.

person Seyit Caglar Abbasoglu    schedule 11.06.2016