Skip to content

Question about Polling transport's close implementation. #120

Open
@Piasy

Description

@Piasy

Hi, I've been working on porting Java implementation of EngineIO and SocketIO to Kotlin Multiplatform recently.

During the development and test process, I have a question about Polling transport's close implementation:
https://github.com/socketio/engine.io-client-java/blob/main/src/main/java/io/socket/engineio/client/transports/Polling.java#L147C1-L167C6

    protected void doClose() {
        final Polling self = this;

        Emitter.Listener close = new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                logger.fine("writing close packet");
                self.write(new Packet[]{new Packet(Packet.CLOSE)});
            }
        };

        if (this.readyState == ReadyState.OPEN) {
            logger.fine("transport open - closing");
            close.call();
        } else {
            // in case we're trying to close while
            // handshaking is in progress (engine.io-client GH-164)
            logger.fine("transport not open - deferring close");
            this.once(EVENT_OPEN, close);
        }
    }

https://github.com/socketio/engine.io-client-java/blob/main/src/main/java/io/socket/engineio/client/Transport.java#L83C1-L94C6

    public Transport close() {
        EventThread.exec(new Runnable() {
            @Override
            public void run() {
                if (Transport.this.readyState == ReadyState.OPENING || Transport.this.readyState == ReadyState.OPEN) {
                    Transport.this.doClose();
                    Transport.this.onClose();
                }
            }
        });
        return this;
    }

Actually if we call transport.close() while the polling transport is still opening, EVENT_OPEN won't be triggered, because doClose will return immediately, and Transport.this.onClose() will be called, then readyState will be CLOSED, and any further response of poll won't trigger EVENT_OPEN, because code logic below:
https://github.com/socketio/engine.io-client-java/blob/main/src/main/java/io/socket/engineio/client/transports/Polling.java#L109C1-L129C11

    private void _onData(Object data) {
        final Polling self = this;
        if (logger.isLoggable(Level.FINE)) {
            logger.fine(String.format("polling got data %s", data));
        }
        Parser.DecodePayloadCallback callback = new Parser.DecodePayloadCallback() {
            @Override
            public boolean call(Packet packet, int index, int total) {
                if (self.readyState == ReadyState.OPENING && Packet.OPEN.equals(packet.type)) {
                    self.onOpen();
                }

                ...
            }
        };

I think the problem is we shouldn't call Transport.this.onClose() in Transport.this.close(), am I right?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions