开发者

Dealing with context of server responses in realtime web applications

Finding it hard to describe this issue - so please edit if you know more relevant terms.

I'm building a web application which essentially uses Redis (PubSub) + Node.js + Socket.IO as a distribution server.

I have two-way communication working with no issues - but I need to be able to make a request to the server from the client (asynchronously) and deal with the response while still processing other irrelevant responses that might come in before it.

This is what I have so far, but I'm not particularly happy with this approach:

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) {
             // call relevant function
         }
     });
 });

 function object_exists(object_id) {
     // do stuff to check object exists
     client.se开发者_如何学Cnd({method: 'object_exists', value: object_exists});
 }

Client

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: I need to 'ask' the server something and then deal with the response using Socket.IO.


You don't specifically say why you are unhappy with your approach, but it looks to me like you are almost there. I am not really sure what you are trying to do with the call array, so I just took it out for clarity.

Basically, you just need to set up a switch statement to act as a message router on each side of the socket connection and fire off the appropriate methods based in incoming messages. Send enough state with the message itself so you can handle the work without any additional context. In your reworked code, I send the object_id to the server and back again to the client.

///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
        }
    }

If you want to see a bunch more code in the same stack doing work similar to what you are trying to accomplish, check out my nodechat.js project.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜