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

fix: fix emitting of events received during connection establishment #695

Closed yifucc closed 2 years ago

yifucc commented 2 years ago

Problem

Hello, there is a bug in the emitting of events received by the client during connection establishment. Since the connection is being established, these events will not be immediately emit to the corresponding listener for processing, but will be stored in a buffer and processed after the connection is established. However, the event name is not removed during processing and is passed to the corresponding listener together.

Here is a demo to reproduce the bug.

Server

netty-socketio version: 1.7.19

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;

public class SocketIOServerApplication {

    public static void main(String[] args) {
        Configuration configuration = new Configuration();
        configuration.setHostname("localhost");
        configuration.setPort(8080);

        SocketIOServer socketServer = new SocketIOServer(configuration);

        // You need to add a custom namespace and listener here.
        // Do not use the default namespace.
        socketServer.addNamespace("/my-namespace").addListeners(new MyNamespaceListener());
        socketServer.start();
    }

    public static class MyNamespaceListener {
        // Listen for the connect event.
        @OnConnect
        public void onConnect(SocketIOClient client) {
            // Send an event here.
            // The event name is debug and the data is "test".
            client.sendEvent("debug", "test");
        }
    }
}

Client

Socket.IO java client version: 1.0.1

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

import java.net.URISyntaxException;
import java.util.Arrays;

public class SocektIOClient {
    public static void main(String[] args) throws URISyntaxException {

        // Establish a connection with the socket-io server through the custom namespace.
        Socket socket = IO.socket("http://localhost:8080/my-namespace");

        // Listen for the event named debug.
        socket.on("debug", new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                // Print the args.
                // The args is [debug, test], which contains the event name, but the expected args is [test].
                System.out.println(Arrays.toString(args));
            }
        });

        socket.open();
    }
}

Here are some screenshots of my debugging.

socketio_1 socketio_2 socketio_3

Solution

It is correct for the client to handle the event in connected status. Just keep consistent with the processing of this.

io.socket.client.Socket#onevent

private void onevent(Packet<JSONArray> packet) {
       ...
        if (this.connected) {
            if (args.isEmpty()) return;
            String event = args.remove(0).toString();
            super.emit(event, args.toArray());
        } else {
            this.receiveBuffer.add(args);
        }
    }
darrachequesne commented 2 years ago

@yifucc good catch, thanks :+1:

jovanbrakus commented 2 years ago

Any plans for releasing new lib with this fix included? Thanks.