3

It's been days that I struggle to make a basic Client / server communication using websockets

My client is a java client with libGDX and my server is a basic java server

My main goal is to compile my client into HTML5 to communicate with my server using websockets.

I tryed the following solution when searching on google :

The 1 seemed to be the best solution but, it doesn't seems to have the TCP_NODELAY socket setting (which is essential in my case)

The 2 seemed an other good solution too, But it relies on http://code.google.com/p/gwt-ws/(which at this time don't understand the point of this)

The 3 is what I choosed, a simple WebSocket Java API to let me write client and server really easily. It worked very well for desktop and android, but when I tryed to html:dist, gradle give me error about websocket which was not inherit etc...

My main build.gradle file contains this line for each project (core, desktop, android, html) : compile "org.java-websocket:Java-WebSocket:1.3.7"

So to resume my primary question : How to correctly establish a websocket connection with a client compiled with GWT in ligdx, with in addition TCP_NODELAY?

My client is a very simple class :

package com.mygdx.game;
import java.net.URI;
import java.nio.ByteBuffer;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;

public class WebSocketsNet extends WebSocketClient {

    public WebSocketsNet(URI serverUri, Draft draft) {
        super(serverUri, draft);
    }

    public WebSocketsNet(URI serverURI) {
        super(serverURI);
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        send("Hello, it is me. Mario :)");
        System.out.println("new connection opened");
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("closed with exit code " + code + " additional info: " + reason);
    }

    @Override
    public void onMessage(String message) {
        System.out.println("received message: " + message);
    }

    @Override
    public void onMessage(ByteBuffer message) {
        System.out.println("received ByteBuffer");
    }

    @Override
    public void onError(Exception ex) {
        System.err.println("an error occurred:" + ex);
    }}
War-sloop
  • 43
  • 6
  • Unfortunately, websockets are rather limited, you don't have the same control over them that you might have for a raw socket - the browser controls most of the socket setup to prevent various kinds of attacks from taking place. This may be one of them - take a look at the websocket spec and other documents that describe it to see what few options are even available over websocket setup https://developer.mozilla.org/en-US/docs/Web/API/WebSocket. On the other hand, might it be sufficient to change this or other settings on the server side, where you have more control? – Colin Alworth Jan 09 '18 at 12:26
  • Hello, and thank you for your answer ! I just saw the mozilla website some days ago. Clearly, yes I can disable the nagle's algorithm on the server side pretty easily ( like : WebSocketServer server = new Server(new InetSocketAddress(host, port)); server.setTcpNoDelay(true);) But does it need to be the same in client so ? or just tcp no delay on server side is more concerned ? – War-sloop Jan 09 '18 at 13:04

2 Answers2

1

Finaly I found a way to make it work, so I post a answer here for those interested.

I used https://github.com/czyzby/gdx-lml/tree/master/websocket

Particulary the example package, and rigorously follow everything that need to be added on build.gradle and on differents xml files, so now it work !

So to conclude :

  • Server Listening websockets with java-web-socket
  • LIBGDX client use gdx-websockets to connect to the server (Watch-out for different build gradle file and xml !!)

Hope to help some people who were in the same problem like me !

Nirostar
  • 189
  • 12
War-sloop
  • 43
  • 6
1

According to https://bugs.webkit.org/show_bug.cgi?id=102079 and https://groups.google.com/forum/#!topic/native-client-discuss/T8zdrMjiTAE, found via https://github.com/websockets/ws/issues/791 and https://github.com/varspool/Wrench/pull/104, most browsers already use TCP_NODELAY. At least from the websocket standard, there is nothing you can do to influence this on the client - on the server there may be more options.

If TCP_NODELAY is already set on the client, you can set it on the server as well to ensure both sides are sending small messages as soon as possible.

Another thought that is suggested in questions like https://stackoverflow.com/a/13406438/860630 is to respond to every message sent right away, so that the network stack flushes all remaining messages as soon as possible.

Colin Alworth
  • 17,801
  • 2
  • 26
  • 39