WebRTC signal server with SSL support written in Go. Supports hosting and joining lobbies. Includes Godot client. I built this to allow WebRTC connections from web builds in Godot which requires SSL. It also works with other build types.
Note: Non-web builds require installing additional WebRTC libraries. See webrtc.html#using-webrtc-in-godot
Note: Currently, it is assumed this will be run somewhere on your LAN and that IPs can be resolved locally. I may extend this in the future for WAN usage.
- /client (
SignalWsClient
class) - Godot client code. Provides aSignalLobby
node via a Godot plugin.SignalLobby
node (signal_lobby_node.gd and signal_lobby_node.tscn) - Handles signals fromSignalWsClient
class and creates a WebRTC mesh using Godot's multiplayer apisSignalWsClient
class (scripts/client.gd) - manages the client websocket connection and aSignalWsPeer
instanceSignalWsMsg
class (scripts/msg.gd) - defines message types and handles serialization / deserialization of messages.SignalWsPeer
class (scripts/peer.gd) -
- /server - Golang signaling server
The server and client communicate over a websocket connection to establish a peer to peer WebRTC connection. Messages are identified by a numeric enum type:
enum Type {
INVALID = 0,
CONNECTED,
HOST,
JOIN,
PEER_CONNECT,
PEER_DISCONNECT,
OFFER,
ANSWER,
CANDIDATE,
SEAL
}
Messages are passing in a simple serialized format in the form of type|pid|data
:
- type - numeric string for the msg type
- pid - peer id identifiying a peer in the WebRTC mesh
- data - optional data used by some message type
The client code can be installed as a Godot plugin
-
Copy the
/client
folder to the/addons
folder in a Godot project -
Enable the
Godot Golang WebRTC Signal
plugin in the Plugins tab of Project settings -
The plugin provides a
SignalLobby
node that can be added to a scene -
After adding the node to a scene, you can right-click on the node and select
% Access as Unique Name
. The node should now show a%
character. -
You can now connect to the
player_added
andlobby_sealed
signals:@onready var signal_lobby = %SignalLobby # SignalLobby node set to "% Access as Unique Name" func _ready() -> void: signal_lobby.player_added.connect(_on_player_added) signal_lobby.lobby_sealed.connect(_on_lobby_sealed)
In the /server
directory, you can start the server by running:
go run cmd/main.go
To use an SSL cert, you'll need to place a .crt
and .key
file in the /server
directory with the same base name.
e.g. ssl.crt
and ssl.key
Then use the -cert
flag to provide the cert base name.
go run cmd/main.go -cert ssl
- To build the server run:
scripts/build.sh
- This will build an executable
build/signalserver
- Copy the executable to wherever you want to run it
To use an SSL cert, you'll need to place a .crt
and .key
file in the same directory as the executable with the same base name.
e.g. ssl.crt
and ssl.key
Then use the -cert
flag to provide the cert base name.
./signalserver -cert ssl
The server can be configured via systemd on a linux server such as a Raspberry Pi.
-
Open a new config file for the service:
sudo nano /etc/systemd/system/gowebrtcsignal.service
-
Copy / paste the following template filling in and placeholders
[Unit] Description = Go WebRTC Signaling Server [Service] Type = simple Restart = always RestartSec = 5s StandardOutput = append:<APPDIR>/stdout.log StandardError = append:<APPDIR>/stderr.log ExecStart = <APPDIR>/signalserver WorkingDirectory = <APPDIR> User = <USER> [Install] WantedBy = multi-user.target
-
Enable and start the service
sudo systemctl enable gowebrtcsignal.service
sudo systemctl start gowebrtcsignal.service
sudo systemctl status gowebrtcsignal.service