Работа с контекстом ответов сервера в веб-приложениях реального времени - PullRequest
1 голос
/ 08 февраля 2011

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

Я создаю веб-приложение, которое по существу использует Redis (PubSub) + Node.js + Socket.IO в качестве сервера распространения.

У меня двусторонняя связь, работающая без проблем, но мне нужно иметь возможность отправлять запрос на сервер от клиента (асинхронно) и обрабатывать ответ, в то же время обрабатывая другие неактуальные ответы, которые могут прийти до .

Это то, что я имею до сих пор, но я не особенно доволен этим подходом:

Сервер

// Lots of other code
redis.psubscribe('*');
redis.on("pmessage", function(pattern, channel, message) {
     // broadcast
});

io.on('connection', function(client) {
     client.on('message', function(message) {
         switch(message.method) {
             // call relevant function
         }
     });
 });

 function object_exists(object_id) {
     // do stuff to check object exists
     client.send({method: 'object_exists', value: object_exists});
 }

Клиент

var call = Array();
$(document).ready(function() {
    socket.connect();
    socket.on("message", function(obj){
        console.log(obj);
        call[obj.method](obj.value);
    });
});

function object_exists(object_id) {
    socket.send({method: 'object_exists', value: object_id});
    // Set a function to be called when the next server message with the 'object_exists' method is received.
    call['object_exists'] = function(value) {
        if(value) {
            // object does exist
        }
    }
}

tl; dr: мне нужно что-то «спросить» у сервера, а затем обработать ответ с помощью Socket.IO.

1 Ответ

1 голос
/ 20 апреля 2011

Вы конкретно не говорите, почему вы недовольны вашим подходом, но мне кажется, что вы почти у цели. Я не совсем уверен, что вы пытаетесь сделать с массивом вызовов, поэтому я просто взял это для ясности.

По сути, вам просто нужно настроить оператор switch, чтобы он действовал как маршрутизатор сообщений на каждой стороне соединения сокета, и запустить соответствующие методы, основанные на входящих сообщениях. Отправьте достаточно сообщения вместе с самим сообщением, чтобы вы могли справиться с работой без какого-либо дополнительного контекста. В вашем переработанном коде я отправляю object_id на сервер и снова обратно клиенту.

///SERVER
// Lots of other code
redis.psubscribe('*');
redis.on("pmessage", function(pattern, channel, message) {
     // broadcast
});

io.on('connection', function(client) {
     client.on('message', function(message) {
         switch(message.method) {
            case 'object_exists':
                object_exists(message.objectId);
            break;
         }
     });
 });

 //Takes an id an returns true if the object exists
 function object_exists(object_id) {
     // do stuff to check object exists
     client.send({method: 'object_exists', objectId: object_id, value: object_exists});
 }

///CLIENT
$(document).ready(function() {

    //setup the message event handler for any messages coming back from the server
    //This won't fire right away
    socket.on("message", function(message){
         switch(message.method) {
            case 'object_exists':
                object_exists(message.objectId, message.value);
            break;
         }
    });

    //When we connect, send the server the message asking if object_exists
    socket.on("connect", function() {
        socket.send({method: 'object_exists', objectId: object_id});
    });

    //Initiate the connection
    socket.connect();
});

//Get's called with with objectId and a true if it exists, false if it does not
function object_exists(objectId, value) {
        if(value) {
            // object does exist, do something with objectId
        }
        else {
            // object does not exist
        }
    }

Если вы хотите увидеть еще кучу кода в одном стеке, выполняющего работу, аналогичную той, которую вы пытаетесь выполнить, посмотрите мой проект nodechat.js .

...