Prevent Theoretical Loss of First Received Message in WebSocket

The server-side code sends a message immediately after opening the connection (it sends the initial configuration / greetings to the client).

And the following code is on the client side:

var sock = new WebSocket(url);
sock.addEventListener('error', processError);
sock.addEventListener('close', finish);
sock.addEventListener('message', processMessage);

I am worried about losing this first configuration / welcome message from the server. Theoretically, nothing prevents him from receiving before the messageevent handler is installed .

On the other hand, it almost never occurred to me. And the AFAIK JavaScript API WebSocket has no countermeasures against this theoretical problem: WebSocket does not allow the installation of an event handler message, nor does it allow creating a WebSocket in a suspended state.

So:

  • - , .
  • JavaScript API WebSocket.
  • , .
  • ( ) , .

?

PS: , Programmers @Stack Exchange? >

+4
3

.

.

: var sock = new WebSocket(url); -. , - , , :

  1. WebSocket, [] [2].

, WebSocket , . :

WebSocket , , .

. , , , WebSocket, . , , .

, , , .

. , , .

" " , ... , .

:

, IO, - , (, , " " ).

EDIT:

, API- Websocket DOM addEventListener.

API Websocket HTML4, - ( EventListener). :.

// altered DOM API:
sock.addEventListener('message', processMessage);
// original WebSocket API:
sock.onmessage = processMessage;

API ( ). , , HTML4.

, addEventListener.

2:

...

, , Ruby Javascript.

Ruby - Websocket ( plezi.io).

Javascript busy-wait, Javascript () (2 ).

onmessage ( 2 ) - , .

, - ( ​​).

, , upgrade ( Iodine C, plezi.io - ).

Ruby:

# run from terminal using `irb`, after `gem install plezi`
require 'plezi'
class WebsocketEcho
    def index
       "Use Websockets"
    end
    def on_message data
       # simple echo
       write data
    end
    def on_open
       # write a welcome message
       # will ths message be lost?
       write "Welcome to the WebSocket echo server."
       puts "New Websocket connection opened, welcome message was sent."
    end
end
# adds mixins to the class and creates route
Plezi.route("/", WebsocketEcho)

# running the server from the terminal
Iodine.threads = 1
Iodine::Rack.app = Plezi.app
Iodine.start

Javascript:

function Client(milli) {
    this.ws = new WebSocket("ws" + window.document.location.href.slice(4, -1));
    this.ws.client = this;
    this.onopen = function (e) { console.log("Websocket opened", e); }
    this.ws.onopen = function (e) { e.target.client.onopen(e); }
    this.onclose = function (e) { console.log("Websocket closed", e); /* reconnect? */ }
    this.ws.onclose = function (e) { e.target.client.onclose(e); }
    if(milli) { // busy wait, blocking the thread.
        var start = new Date();
        var now = null;
        do {
            now = new Date();
        } while(now - start < milli);
    }
    this.onmessage = function (e) { console.log(e.data); }
    // // DOM API alternative for testing:
    // this.ws.addEventListener('message', function (e) { e.target.client.onmessage(e); });
    // // WebSocket API for testing:
    this.ws.onmessage = function (e) { e.target.client.onmessage(e); }    
}
// a 2 second window
cl = new Client(2000);

(MacOS):

  • Safari 11.01 Websocket ( , , Ruby). , , .

  • Chrome 62.0 Websocket. 2- . , , onmessage.

  • FireFox 56.0 , Chrome, Websocket. 2- . .

- Windows Linux, ... , . , .

+5

.

chrome 62 ubuntu 1404, chrome 127.0.0.1. . . mac chrome 62. , , . , . .

:

var ws = new WebSocket(url);
var lastConnectTime = new Date();
ws.onerror = processError;
ws.onclose = finish;
ws.onmessage = processMessage;

, ( ), .

js :

var ws = new WebSocket(url);
var lastConnectTime = new Date();
ws.onerror = processError;
ws.onclose = finish;
ws.onmessage = processMessage;
ws.onopen = function(){
   ws.send("{}");
};

golang:

func (s *GoServer)ServeHTTP(w http.ResponseWriter, r *http.Request){
    fmt.Println("WebsocketServeHttp recv connect",r.RemoteAddr)
    conn,err:=websocket.Upgrade(w,r,nil,10240,10240)
    if err!=nil{
        panic(err)
    }
    _,_,err=conn.ReadMessage()
    if err!=nil{
        panic(err)
    }
    //... (you can send message to the client now)
}
+1

, ( , ) Chrome 62 63 Ubuntu: . tcpdump, , . "" -. onopen callback, onmessage .

, , , WebKit- WebSocket, , Mac Mac Firefox, , Chrome on Ubuntu .

+1

Source: https://habr.com/ru/post/1625121/


All Articles