Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronous request with Websockets

I can send and receive messages from server on websockets. I need to write a function that will send data to the server and is awaiting a response from the server and then return it as a result of a function.

Send:

ws.send('my_message_to_server');

Receive (it's a event):

ws.bind('message', function(message) {
console.log(message);
});

My function:

function request(message){
ws.send(message);
    //How wait for receive???
    return response;
}
like image 510
Artur Khachuyan Avatar asked Nov 16 '12 12:11

Artur Khachuyan


People also ask

Is WebSocket send synchronous?

Websocket connections are fully asynchronous, unlike HTTP/1.1 (synchronous) and HTTP/2 (asynchronous, but the server can only initiate streams in response to requests). With Websocket, the client and the server can both send frames at any time without any restriction.

Why WebSockets are not reliable?

It is worth to mention that WebSockets give us only an illusion of reliability. Unfortunately, the Internet connection itself is not reliable. There are many places when the connection is slow, devices often go offline, and in fact, there is still a need to be backed by a reliable messaging system.

Can WebSocket send and receive at the same time?

The key word in that definition is two-way: with WebSocket, both the client and the server can trigger communication with one another, and both can send messages, at the same time.

Why WebSockets are not used?

Avoid using WebSockets if only a small number of messages will be sent or if the messaging is very infrequent. Unless the client must quickly receive or act upon updates, maintaining the open connection may be an unnecessary waste of resources.


2 Answers

There's a neat way I used in some online game a while ago, but you will need to change stuff on the server side as well !

1st make a function to send the data

var socketQueueId = 0;
var socketQueue = {};

function sendData(data, onReturnFunction){
    socketQueueId++;
    if (typeof(returnFunc) == 'function'){
        // the 'i_' prefix is a good way to force string indices, believe me you'll want that in case your server side doesn't care and mixes both like PHP might do
        socketQueue['i_'+socketQueueId] = onReturnFunction;
    }
    jsonData = JSON.stringify({'cmd_id':socketQueueId, 'json_data':data});
    try{
        webSocket.send(jsonData);
        console.log('Sent');
    }catch(e){
        console.log('Sending failed ... .disconnected failed');
    }
}

Then in the server side, when processing the request, you should send the cmd_id back to the client with the response

webSocket.onmessage = function(e) {

    try{
        data = JSON.parse(e.data);
    }catch(er){
        console.log('socket parse error: '+e.data);
    }

    if (typeof(data['cmd_id']) != 'undefined' && typeof(socketQueue['i_'+data['cmd_id']]) == 'function'){
        execFunc = socketQueue['i_'+data['cmd_id']];
        execFunc(data['result']);
        delete socketQueue['i_'+data['cmd_id']]; // to free up memory.. and it is IMPORTANT thanks  Le Droid for the reminder
        return;
    }else{
        socketRecieveData(e.data);
    }
}

and create a function to handle all other types of returns:

socketRecieveData(data){
    //whatever processing you might need
}

so now simply if you want to send some data for the server and wait for response for that specific data you simple do:

sendData('man whats 1+1', function(data){console.log('server response:');console.log(data);});
like image 138
Rami Dabain Avatar answered Oct 23 '22 17:10

Rami Dabain


When you create a websocket, you usually add a onmessage callback function to the socket which is called whenever the client receives data from the server.

 var socket = new WebSocket("ws://example.com:8000/websocketapp.php");  
 socket.onmessage = function(msg){
      alert('The server says: ' + msg);
 }

A function which blocks until the server responds is a bad idea conceptually, because it means that the script execution will hang until the answer from the server came in. When the server is busy and the network latency is high, this can take several seconds. For that reason it is better to work with callback functions (functions which are called when an event happens).

When you can guarantee that you only send one request at a time to the server, you can just change the socket.onmessage function to a function which processes the servers response and acts on it:

 socket.onopen = function() {
    socket.send("What's your name?");
    socket.onmessage = function(message) {
        alert("The server says its name is " + message); 
        socket.send("What is the answer to life, the universe and everything?");
        socket.onmessage = function(msg){
             alert("The server says the answer is: " + msg);
        }
     }
 }

(By the way: I wrote the request before setting the reply handler for better readability. It would be better to do it the other way around: set the reply handler first and then send the request. This is important for the unlikely but not impossible case that the server responds so fast that the handler wasn't set up yet).

But when you have multiple parallel requests and you need to find out which request the server is referring to, you will need something better. You could, for example, have an onmessage function which identifies the message and then forwards each message to a specialized message handler function.

like image 36
Philipp Avatar answered Oct 23 '22 19:10

Philipp