Starscream icon indicating copy to clipboard operation
Starscream copied to clipboard

disconnected, viabilityChanged, close, seem to be completely not working????

Open smhk opened this issue 3 years ago • 8 comments

Start a connection to your websocket server.

On the server, kill the server.

In starscream, nothing happens.

There is no connected, disconnected, viabilityChanged or reconnectSuggested call.

This seems bizarre. Have tested extensively on many phones, etc.

Any ideas? Kindly ...

smhk avatar Nov 22 '21 12:11 smhk

This is definitely a bug. I have a similar issue and spent a lot of time debugging it.

As a result, I noticed that if TCPTransport is used as transport for WSEngine if the server is killed or the connection is killed by the server we get a message that is not handled.

What do I mean by that is this:

Screenshot 2022-02-24 at 14 51 46

If the connection is closed from the server-side this closure passed into func receive simply returns without calling delegate or doing anything. Note, that data is nil in this case:

Screenshot 2022-02-24 at 14 55 18

JeneaVranceanu avatar Feb 24 '22 12:02 JeneaVranceanu

I will open a PR with the bug fix soon.

Note: I'm working on a project related to blockchain and we are using a load balancer to keep nodes stable and not busy with obsolete connections. By default every 30 seconds it drops created connection. This bug basically renders the Starscream library unusable within this context but it is a dependency of web3swift which makes it a pain to fix. "Luckily", web3swift has its own bugs that made us use our own fork of it (because PRs are waiting to be merged).

Will use one more fork but will be happy to switch back to the original repository later! ❤️ 🙂

JeneaVranceanu avatar Feb 24 '22 13:02 JeneaVranceanu

Also, none of these handlers are called:

conn.stateUpdateHandler
conn.viabilityUpdateHandler

JeneaVranceanu avatar Feb 24 '22 13:02 JeneaVranceanu

Update: there is a comment that says

// Refer to https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework

I was wondering if my understanding of the implementation is wrong. Instead, I've found the section this comment refers to within that tutorial. Cannot paste a link to it directly, that section starts with "In schedule_next_receive you must handle three cases:".

And the first case described in this section is the one where the remote peer has closed the connection. The first case says:

If you just received the end of the data stream, call exit to terminate the program. This is how the program stops when the remote peer closes the network connection.

This is how it's done in Objective-C example:

    if (is_complete &&
        (context == NULL || nw_content_context_get_is_final(context))) {
        exit(0);
    }

And looks like there was a misunderstanding when this case was handled in Swift in the Starscream library. exit(0); is not the same as return. exit(0); is more like a connection?.cancel() that is used in func disconnect() declared in TCPTransport class.

JeneaVranceanu avatar Feb 24 '22 13:02 JeneaVranceanu

It also explains why stateUpdateHandler and viabilityUpdateHandler are not called.

JeneaVranceanu avatar Feb 24 '22 13:02 JeneaVranceanu

Was also experiencing this issue and believe you're right about this @JeneaVranceanu - hopefully your PR can get merged, appreciate the fix.

Update: there is a comment that says

// Refer to https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework

I was wondering if my understanding of the implementation is wrong. Instead, I've found the section this comment refers to within that tutorial. Cannot paste a link to it directly, that section starts with "In schedule_next_receive you must handle three cases:".

And the first case described in this section is the one where the remote peer has closed the connection. The first case says:

If you just received the end of the data stream, call exit to terminate the program. This is how the program stops when the remote peer closes the network connection.

This is how it's done in Objective-C example:

    if (is_complete &&
        (context == NULL || nw_content_context_get_is_final(context))) {
        exit(0);
    }

And looks like there was a misunderstanding when this case was handled in Swift in the Starscream library. exit(0); is not the same as return. exit(0); is more like a connection?.cancel() that is used in func disconnect() declared in TCPTransport class.

matthewoleary avatar Apr 19 '22 19:04 matthewoleary

@matthewoleary Hey, thanks for taking time to understand what I've tried to explain! I also hope this PR will be merged but I'm afraid it won't happen any time soon or maybe even at all. What I can suggest is that if you are using Carthage or SPM just switch to my fork temporarily. Not sure about CocoaPods though. Had a few discussions with other Swift developers and one of the thoughts about Starscream library development was that supposedly it's not maintained as actively as it was before in favor of websocket implementation provided from Apple's SDKs.

Starscream is a great tool and I'd gladly use it but right now it seems that it's getting stale as some PRs are 2 or 3 years old.

JeneaVranceanu avatar Apr 19 '22 19:04 JeneaVranceanu

Agreed @JeneaVranceanu, with newer URLSessionWebSocketTask APIs being iOS 13+ this is still a great library to use above and below iOS 13. Hopefully this library can get some love again and we can get more 👀 on this critical issue. My kudos to you for finding a fix!

matthewoleary avatar Apr 19 '22 22:04 matthewoleary