Skip to content

Allow StreamPeerTCP to be ugpraded to a WebSocketPeer after headers are examined #12756

Open
godotengine/godot
#107871
@Portponky

Description

@Portponky

Describe the project you are working on

I'm working on a jackbox-style local co-op game, where the main game is written in Godot, and players connect via their smartphones. The smartphone side of things is HTML/js, and connects to the Godot game via websockets. The Godot game acts as the central focus, with players making choices and getting information through their phones.

Describe the problem or limitation you are having in your project

You can only upgrade a SteamPeerTCP to a websocket if it has the complete websocket header in its buffer. If you read the buffer, such as to find out what is being requested, you can no longer upgrade to a websocket.

For example, if I have:
/index.html which contains the game, javascript, etc.
/ws as an endpoint for the websocket connection

Then if the stream has bytes available, I need to read those bytes to see if there's a GET /index.html or GET /ws. Once those bytes are read, WebSocketPeer.accept_stream will no longer be able to upgrade.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The solution I propose is to allow the received headers to be passed to WebSocketPeer.accept_stream so that it can form the complete header prior to upgrading to a websocket connection. This can be an additional parameter which defaults to an empty string, so it will not affect compatibility.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Pull request available at godotengine/godot#107871

The received headers are used to populate the handshake buffer, and the ordering for how it checks for the handshake buffer being ready is tweaked slightly. I am using this change in my game and have tested it with players over the internet and locally.

If this enhancement will not be used often, can it be worked around with a few lines of script?

This is very niche, but it's also very low impact.

The alternatives are either rewriting the websocketpeer in gdscript (performance concerns, redundant effort), or providing two endpoints - one for http and one for websockets. Two endpoints is annoying for users, especially when you factor in offering endpoints through firewalls or routers. Offering a single unified endpoint is the whole reason websockets are upgraded from http connections.

Is there a reason why this should be core and not an add-on in the asset library?

Godot can already do all these things individually in core, it just needs a small change to do them all seamlessly.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions