Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive websocket-messages from Vert.x server in Javascript?

I am trying to create an http-server including websockets with Vert.x in Java, while writing the client in Javascript without vertx.js. I avoid using Vert.x in the client because it should stay browserbased (tools like browserfy didn't succeed in converting the CommonJS-standard of Vert.x into code which can be used by browsers).

After completing test-code for both server and client, I tried the simple example of sending a message to the server, getting its data and answering with an arbitrary response. The server received the message and was able to read the content. However, the client only received a message without getting the assumed content. The client wasn't able to convert the event-data received by the websocket to a string (no string-data at all?). Using indexof.js to determine byte-size of the event-data resulted in a constant size of 34 bytes after varying the content, sent by the server, several times. I tried to use the writeMessage as well as write-method on the serverside to send data to the client-websocket. The results stayed the same.

Why does my client only receive data of constant size on the websocket and how to make it work?

Thank your for your suggestions!

EDIT: I exchanges the methods write and writeMessage with the use of writeFrame. With writeFrame one can send binary data as well as plain text. Sending text this way from the Java-based server to the Javascript-based client works fine. I still don't know how to handle binary messages on the clientside, but it would be beneficial nontheless. While text-messages work, they are assumed to still have the same size (34 byte). I thought the received data-object would vary in size but it seems, it is just an object which somewhere points to the actual data.

------------------------------------------------

The client-code was written during (successful) tests with Java Servlets and websockets:

var wsUri = "ws://" + document.location.host + document.location.pathname + "chat";

var websocket = new WebSocket(wsUri);
websocket.onerror = function(evt) { onError(evt) };
websocket.onopen = function (evt) { onOpen(evt) };

function onError (evt)
{
    debugMessage('<span style="color: red;">ERROR:</span> ' + evt.data);
}

function onOpen (evt)
{
//    debugMessage("Connected to " + wsUri);
    debugMessage("GOTCHA!");
}

websocket.onmessage = function (evt) { onMessage(evt) };

function onMessage (evt)
{
    debugMessage(evt.toString());
    debugMessage(evt.data.toString());
    debugMessage(sizeof(evt.data));
}

function sendMessage (msg)
{
    websocket.send(msg);
}

function sendDebugMessage ()
{
    websocket.send("Hiho Wursty!");
    debugMessage("Did send Wursty-message.");
}

The serverside is according to the official Vert.x-documentation as well as another another online-tutorial:

server = vertx.createHttpServer();

server.requestHandler(request -> {
    handleRequest(request);
});

server.websocketHandler(ws -> {
    print("Websocket-handshake...");
    print("path = " + ws.path());
    print("uri = " + ws.uri());
    print("localAdress = " + ws.localAddress().toString());
    print("remoteAddress = " + ws.remoteAddress());
    print(ws.toString());

    if (!ws.path().equals("/chat")) {
        ws.reject();
    } else {
        SharedData sd = vertx.sharedData();
        LocalMap<String, String> wsChatSessions =
                sd.getLocalMap("ws.chat.sessions");

        wsChatSessions.put(ws.textHandlerID(), ws.toString());

        ws.closeHandler(ch -> {
            print("Closing ws-connection to client " + ws.textHandlerID());
            wsChatSessions.remove(ws.textHandlerID());
        });

        ws.handler(new Handler<Buffer>(){
            @Override
            public void handle(final Buffer data) {
                String msg = data.getString(0, data.length());
                print("Message from ws-client " + ws.textHandlerID() 
                        + ": " + msg);
                Buffer resp = Buffer.buffer();
                resp.appendString("O Ding Dong asd asda sdasd a"
                        + "asdasd asd asdasda sdas dasd adads asd as"
                        + "as dasd asd asd asd asdasd asdasdasd "
                        + "asdasd asd asd asd asd asda sdasd asd !");
                ws.writeMessage(resp);
                ws.write(resp);
            }
        });
    }
});

server.listen(port, res -> {
    if (res.succeeded()){
        print("Listening...");
    } else{
        print("Failed to bind! -> Server is not listening"
            + " to incoming client connections.");
    }
});
like image 402
Florian R. Klein Avatar asked Sep 15 '25 17:09

Florian R. Klein


1 Answers

The reason, I received only messages of 0 bytes size was relatively simple: In the Javascript-websocket, one can define the type of (binary) data received by the websocket from the server, the binaryType. As default, it is set "blob". In my case, I assumed to receive arraybuffers. Setting the option accordingly made the websocket pass down the data as expected:

websocket.binaryType = "arraybuffer";

To use it, it is still necessary to create an array from the arraybuffer. In my case, I created an array of unsigned 8-Bit-integers:

var dataBytes = new Uint8Array(evt.data);

Now the data is ready to be processed by subsequent code.

like image 118
Florian R. Klein Avatar answered Sep 18 '25 06:09

Florian R. Klein