socketio / socket.io-client-java

Full-featured Socket.IO Client Library for Java, which is compatible with Socket.IO v1.0 and later.
https://socketio.github.io/socket.io-client-java/installation.html
Other
5.32k stars 972 forks source link

Failed to Connect to socket.io implemented simple server - No Specific Reason Given #709

Open oliTheTM opened 2 years ago

oliTheTM commented 2 years ago

Describe the bug I continuously get a generic error upon attempting to connect with a simple socket.io implemented server; as a client. The error is: server error.

To Reproduce Server Socket.IO server version: unknown

Client Socket.IO java client version: 2.0.1

public class Callback
  {
    private final int MAX_RECONNECTION_ATTEMPTS;
    private Socket client;
    private CountDownLatch awaiter;

    public Callback(String url) {
      MAX_RECONNECTION_ATTEMPTS = ConfigHandler.getInstance().getWebSocketSettings().getMaxConnectionRetries();
      try{
        client = IO.socket(
          (new URI(url)),
          IO.Options.builder().setTimeout(60000).build()
        );
      } catch (URISyntaxException e) {
        System.err.println(e.getMessage());
      }
      awaiter = new CountDownLatch(1);
    }

    private void await() {
      try{
        awaiter.await(client.io().timeout(), TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        await();
      }
    }
    private void resetAwaiter() {
      awaiter = new CountDownLatch(1);
    }
    private void _connect() {
      //setup lifecycle listeners:
      if (!client.hasListeners(Socket.EVENT_CONNECT))
        client.once(Socket.EVENT_CONNECT, ((Emitter.Listener)(args) -> {
        LOG.info(
         "*CaseWorker (" + ConfigHandler.getInstance().getConfig().getTestEnvironment() +
          ")  WEBSOCKET CONNECTED*"
        );
        awaiter.countDown();
      }));
      client.once(Socket.EVENT_CONNECT_ERROR, ((Emitter.Listener)(args) -> {
        StringBuilder fold = new StringBuilder();
        for (Object arg : args) {
          if (arg instanceof Exception)
            fold.append(System.lineSeparator()).append(((Exception)arg).getMessage());
        } LOG.info(
          "*CaseWorker ("+ConfigHandler.getInstance().getConfig().getTestEnvironment()+
          ")  WEBSOCKET CONNECTION ERROR*: "+fold.toString()
        );
        awaiter.countDown();
      }));
      if (!client.hasListeners(Socket.EVENT_DISCONNECT))
        client.on(Socket.EVENT_DISCONNECT, ((Emitter.Listener)(args) -> {
        StringBuilder fold = new StringBuilder();
        for (Object arg : args) {
          if (arg instanceof String)
            fold.append(System.lineSeparator()).append((String)arg);
        } LOG.info(
          "*CaseWorker (" + ConfigHandler.getInstance().getConfig().getTestEnvironment() +
          ")  WEBSOCKET DISCONNECTED*: " + fold.toString()
        );
      }));

      client.open().connect();

      //await connection or err:
      await();
      resetAwaiter();
    }
    public void connect() throws SocketIOException {
      int remainingAttempts = MAX_RECONNECTION_ATTEMPTS;
      while ((remainingAttempts > 0)&&(!client.connected())){
        LOG.info(
          '*'+TestHelpers.ordinalOf(MAX_RECONNECTION_ATTEMPTS - remainingAttempts + 1)+
          " ATTEMPT TO ESTABLISH WEBSOCKET WITH CaseWorker ("+
          ConfigHandler.getInstance().getConfig().getTestEnvironment()+")* ..."
        );
        _connect();
        --remainingAttempts;
      }
      if (!client.connected())
        throw new SocketIOException(
          "*COULD NOT ESTABLISH WEBSOCKET WITH CaseWorker (" +
          ConfigHandler.getInstance().getConfig().getTestEnvironment()+
        ")*");
    }
    public void awaitCaseUpdated(@NotNull() String caseID) throws SocketIOException {
      if (client.connected()) {
        client.emit("joinRoom", caseID).
          once("joinRoom", ((Emitter.Listener)((msg) -> {
            LOG.info("*joinRoom*: "+ Arrays.toString(msg));
            //@TODO: assumption that it's the 2nd component
            if (msg[1] instanceof String) {
              if (((String)msg[1]).contains("caseUpdated"))
                awaiter.countDown();
            }
          })));
        await();
        resetAwaiter();
      } else
        throw new SocketIOException("Cannot awaitCaseUpdated as not connected yet");
    }
    public void disconnect() throws SocketIOException {
      if (client.connected())
        client.disconnect().close();
      else
        throw new SocketIOException("cannot disconnect given no connection");
    }
  }

Then, this class is applied in another class:

//omitted..
//in the constructor:
callback = new Callback(
      ConfigHandler.getInstance().getWebSocketSettings().getCarFinanceEndpoint() +
      "&token="+getToken()
    );
//omitted..
public void awaitCallbackForCase(String caseID) throws SocketIOException {
      callback.connect();
      callback.awaitCaseUpdated(caseID);
      callback.disconnect();
  }

Expected behavior Should, at least, successfully connect.

Platform:

Additional context I am only trying to 'listen' on 1 event joinRoom. Then I literally just wait until some new record pattern-matches caseUpdated.

oliTheTM commented 2 years ago

False-Positive?

darrachequesne commented 2 years ago

Hi! Do you know the version of the server? You can check the compatibility table here: https://socketio.github.io/socket.io-client-java/installation.html

Regarding your reconnection logic, you can listen to the events sent by the underlying Manager:

public class Fiddle {

    public static void main(String[] argz) {
        IO.Options options = IO.Options.builder()
                .setReconnectionAttempts(10)
                .build();

        final Socket socket = IO.socket(URI.create("http://localhost:8080"), options);

        socket.io().on(Manager.EVENT_RECONNECT_ERROR, (args) -> {
            // reconnection attempt has failed
        });

        socket.io().on(Manager.EVENT_RECONNECT_FAILED, (args) -> {
            // all reconnection attempts have failed
        });

        socket.connect();
    }
}
oliTheTM commented 2 years ago

Hi! Do you know the version of the server? You can check the compatibility table here: https://socketio.github.io/socket.io-client-java/installation.html

Regarding your reconnection logic, you can listen to the events sent by the underlying Manager:

public class Fiddle {

    public static void main(String[] argz) {
        IO.Options options = IO.Options.builder()
                .setReconnectionAttempts(10)
                .build();

        final Socket socket = IO.socket(URI.create("http://localhost:8080"), options);

        socket.io().on(Manager.EVENT_RECONNECT_ERROR, (args) -> {
            // reconnection attempt has failed
        });

        socket.io().on(Manager.EVENT_RECONNECT_FAILED, (args) -> {
            // all reconnection attempts have failed
        });

        socket.connect();
    }
}

Sorry, I don't know the version of the associated server. I'll try out those extra listeners to see what new information they can provide.

Thanks.

oliTheTM commented 2 years ago

Ok, so I applied the following 2 listeners to client which is of type Socket:

client.io().on(Manager.EVENT_RECONNECT_ERROR, (args) -> {
        StringBuilder fold = new StringBuilder();
        LOG.info("*WEBSOCKET RECONNECT ERROR*:");
        for (Object arg : args) {
          if (arg.getClass().isPrimitive())
            fold.append(arg.toString());
          else if (arg instanceof String)
            fold.append((String)arg);
        }
        LOG.info(fold.toString());
      });
      client.io().on(Manager.EVENT_RECONNECT_FAILED, (args) -> {
        StringBuilder fold = new StringBuilder();
        LOG.info("*WEBSOCKET RECONNECT FAILED ERROR*:");
        for (Object arg : args) {
          if (arg.getClass().isPrimitive())
            fold.append(arg.toString());
          else if (arg instanceof String)
            fold.append((String)arg);
        }
        LOG.info(fold.toString());
      });

However, I didn't receive any new information; instead, I get the same vague server error:

Apr 23, 2022 12:35:15 PM domain.actors.CaseWorker$Callback connect
INFO: *1st ATTEMPT TO ESTABLISH WEBSOCKET WITH CaseWorker (sit)* ...
Apr 23, 2022 12:35:16 PM domain.actors.CaseWorker$Callback lambda$_connect$3
INFO: *CaseWorker (sit)  WEBSOCKET CONNECTION ERROR*: 
server error
Apr 23, 2022 12:35:16 PM domain.actors.CaseWorker$Callback connect
INFO: *2nd ATTEMPT TO ESTABLISH WEBSOCKET WITH CaseWorker (sit)* ...
Apr 23, 2022 12:35:17 PM domain.actors.CaseWorker$Callback lambda$_connect$3
INFO: *CaseWorker (sit)  WEBSOCKET CONNECTION ERROR*: 
server error

Etc..

Any idea how I can uncover the root cause?? @bazza @mdawaffe @lu-zero @b95505017 @pamepros

oliTheTM commented 2 years ago

Is anyone there??... -___-

xtr1993 commented 2 years ago

client.io().on(Manager.EVENT_RECONNECT_ERROR, (args) -> { StringBuilder fold = new StringBuilder(); LOG.info("WEBSOCKET RECONNECT ERROR:"); for (Object arg : args) { if (arg.getClass().isPrimitive()) fold.append(arg.toString()); else if (arg instanceof String) fold.append((String)arg); } LOG.info(fold.toString()); });

Hi,I have a question about your code: you create StringBuilder fold = new StringBuilder(); in socket.on()

have you tried creating a global variable to append these args? @oliTheTM