godot-webrtc-mplayer-testing/scripts/global/signaller_client.gd

199 lines
6 KiB
GDScript3
Raw Normal View History

2021-11-15 15:02:55 -06:00
extends Node
2021-11-17 08:18:12 -06:00
"""
This module is responsible for making a WebSocket connection to the signaller
in order to enable establishish WebRTC P2P connections. Another module is
2021-12-08 23:39:56 -06:00
expected to fully setup the peer connections.
2021-11-17 08:18:12 -06:00
"""
2021-12-08 23:39:56 -06:00
const DISPLAY_NAME_FILE = "user://display_name.txt"
const DEFAULT_DISPLAY_NAME = "UnnamedPlayer"
# lobby data
2021-12-09 21:10:17 -06:00
signal lobby_data(lobbies)
2021-12-08 23:39:56 -06:00
signal lobby_joined(lobby_and_peer)
2021-11-17 13:57:45 -06:00
signal lobby_left(id)
2021-12-08 23:39:56 -06:00
signal lobby_delete(id)
2021-12-07 16:43:37 -06:00
2021-12-08 23:39:56 -06:00
# peer data
2021-12-09 21:10:17 -06:00
signal peer_data(peers)
2021-11-17 13:57:45 -06:00
signal peer_left(id)
2021-12-09 21:10:17 -06:00
signal peer_init(peer_id)
2021-12-08 23:39:56 -06:00
# WebRTC negotiations
signal candidate_received(cand)
2021-11-17 16:24:00 -06:00
signal offer_received(data)
signal answer_received(data)
2021-11-17 13:57:45 -06:00
2021-12-08 23:39:56 -06:00
# underlying websocket
signal received_message
signal connected
signal connection_failure
signal disconnected
2021-11-17 08:18:12 -06:00
2021-12-08 23:39:56 -06:00
onready var websocket: WebSocketClient = WebSocketClient.new()
# TODO: setget these?
2021-11-17 16:24:00 -06:00
onready var client_id = null
2021-12-08 23:39:56 -06:00
onready var display_name = DEFAULT_DISPLAY_NAME setget set_display_name
2021-11-17 16:24:00 -06:00
onready var peer_id = null
2021-12-07 09:32:20 -06:00
2021-12-09 21:10:17 -06:00
onready var lobby_data = null
2021-12-08 23:39:56 -06:00
var websocket_url = null
2021-12-07 16:09:50 -06:00
2021-12-08 23:39:56 -06:00
func _init(url):
websocket_url = url
2021-11-17 13:57:45 -06:00
2021-11-17 08:18:12 -06:00
func _ready():
2021-12-08 23:39:56 -06:00
display_name = _load_display_name()
websocket.connect("data_received", self, "_handle_data")
websocket.connect("connection_established", self, "_connected")
# websocket.connect("connection_succeeded", self, "_connection_succeeded")
websocket.connect("connection_closed", self, "_closed")
websocket.connect("connection_error", self, "_connection_error", [false])
websocket.connect("connection_failed", self, "_connection_error", [false])
websocket.connect("server_close_request", self, "_close_request")
func connect_websocket():
2021-11-17 08:18:12 -06:00
close()
2021-12-08 23:39:56 -06:00
print("Attempting to connect to WebSocket signalling server at %s" % websocket_url)
var result = websocket.connect_to_url(websocket_url)
2021-12-03 17:05:31 -06:00
if result != OK:
2021-12-08 23:39:56 -06:00
print("Failed to connect to WebSocket signalling server at %s: %s" % [websocket_url, result])
2021-11-15 15:02:55 -06:00
2021-12-08 23:39:56 -06:00
func close():
websocket.disconnect_from_host()
2021-11-15 15:02:55 -06:00
2021-12-08 23:39:56 -06:00
func set_display_name(new_display_name: String):
display_name = new_display_name
_send("update_display_name:%s" % display_name)
2021-11-15 15:02:55 -06:00
2021-12-08 23:39:56 -06:00
func request_lobby_list():
return _send("request_lobby_list")
2021-11-17 08:18:12 -06:00
2021-11-17 13:57:45 -06:00
func join_lobby(id: String):
return _send("lobby_join:%s" % id)
2021-11-17 08:18:12 -06:00
2021-11-17 13:57:45 -06:00
func create_lobby():
return _send("lobby_create")
2021-11-17 08:18:12 -06:00
2021-12-08 23:39:56 -06:00
func is_host(): return peer_id == 1
2021-11-17 08:18:12 -06:00
2021-12-07 16:09:50 -06:00
func set_lobby_name(s: String):
2021-12-08 23:39:56 -06:00
if is_host(): _send_json({"name": s}, "update_lobby")
2021-12-07 16:09:50 -06:00
func lock_lobby():
2021-12-08 23:39:56 -06:00
if is_host(): _send_json({"locked": true}, "update_lobby")
2021-12-07 16:09:50 -06:00
func set_lobby_max_players(n: int):
2021-12-08 23:39:56 -06:00
if is_host(): _send_json({"maxPlayers": n}, "update_lobby")
func request_peer_list(): _send("request_peer_list")
func send_candidate(peerId, mid, index, sdp) -> int:
return _send_json({"peerId": peerId, "mid": mid, "index": index, "sdp": sdp}, "candidate")
func send_offer(peerId, offer) -> int:
return _send_json({"peerId": peerId, "offer": offer }, "offer")
func send_answer(peerId, answer) -> int:
return _send_json({"peerId": peerId, "answer": answer }, "answer")
2021-12-07 16:09:50 -06:00
2021-12-09 21:10:17 -06:00
func get_lobby_name(): return lobby_data.name
2021-12-08 23:39:56 -06:00
func _closed(code):
print("WebSocket closed: %s: " % code)
emit_signal("disconnected")
2021-12-07 16:43:37 -06:00
2021-12-08 23:39:56 -06:00
func _close_request(code: int, reason: String):
print("Received WebSocket close request from signalling server - Code: %s, Reason: %s" % [code, reason])
# TODO: does this fire _closed?
func _connected(protocol = ""):
print("Signaller connected via WebSocket using protocol %s" % protocol)
websocket.get_peer(1).set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
emit_signal("connected")
_send_json({name = display_name}, "init")
func _process(_delta: float):
var status: int = websocket.get_connection_status()
if status == WebSocketClient.CONNECTION_CONNECTED or status == WebSocketClient.CONNECTION_CONNECTING:
websocket.poll()
func _handle_data():
var msg: String = websocket.get_peer(1).get_packet().get_string_from_utf8()
2021-11-17 13:57:45 -06:00
if msg.begins_with("json:"):
var data = JSON.parse(msg.substr(5))
if data.error == OK:
2021-12-08 23:39:56 -06:00
_process_message(data.result)
var _result = websocket.get_peer(1).put_packet("".to_utf8())
2021-11-17 13:57:45 -06:00
else:
2021-12-09 21:10:17 -06:00
var d = msg.split(":", false, 2)
_process_message({type = d[0], data = d[1]})
2021-11-17 13:57:45 -06:00
2021-12-08 23:39:56 -06:00
func _process_message(data: Dictionary):
2021-11-17 13:57:45 -06:00
match data["type"]:
2021-12-08 23:39:56 -06:00
"init":
client_id = data.id
print("Signaller Received init response: %s" % data)
2021-12-09 21:10:17 -06:00
"init_peer":
print("init_peer: %s" % data)
peer_id = int(data.data)
emit_signal("peer_init", peer_id)
2021-12-02 16:09:43 -06:00
2021-12-09 21:10:17 -06:00
"lobby_data": emit_signal("lobby_data", data.data)
2021-12-08 23:39:56 -06:00
"lobby_delete": emit_signal("lobby_delete", data.id)
2021-12-02 16:09:43 -06:00
2021-11-17 13:57:45 -06:00
"lobby_joined":
2021-12-09 21:10:17 -06:00
print("lobby_joined: %s" % data)
lobby_data = data
2021-12-08 23:39:56 -06:00
emit_signal("lobby_joined", data)
2021-11-17 13:57:45 -06:00
"lobby_left":
2021-12-08 23:39:56 -06:00
peer_id = null
2021-11-17 13:57:45 -06:00
emit_signal("lobby_left", data["id"])
2021-12-02 16:09:43 -06:00
2021-12-08 23:39:56 -06:00
"peer_data":
2021-12-09 21:10:17 -06:00
emit_signal("peer_data", [data] if data.has("id") else data["data"])
2021-12-06 16:27:16 -06:00
"peer_left":
print("Peer Left: %s" % data)
emit_signal("peer_left", data["data"])
2021-12-02 16:09:43 -06:00
2021-11-17 16:24:00 -06:00
"candidate":
2021-12-09 21:10:17 -06:00
print("Candidate received - Data: %s" % JSON.print(data))
emit_signal("candidate_received", data)
2021-11-17 16:24:00 -06:00
"offer":
2021-12-09 21:10:17 -06:00
print("Offer received - Data: %s" % JSON.print(data))
emit_signal("offer_received", data)
2021-11-17 16:24:00 -06:00
"answer":
2021-12-09 21:10:17 -06:00
print("Answer received - Data: %s" % JSON.print(data))
emit_signal("answer_received", data)
2021-12-07 12:33:09 -06:00
"ping":
_send("pong")
2021-12-02 15:13:12 -06:00
_: print("Unhandled Message - Data: %s" % JSON.print(data))
2021-11-17 08:18:12 -06:00
2021-12-08 23:39:56 -06:00
func _load_display_name():
var _display_name = DEFAULT_DISPLAY_NAME
var display_name_file = File.new()
if display_name_file.open(DISPLAY_NAME_FILE, File.READ) == OK:
_display_name = display_name_file.get_as_text()
else:
print("Failed to open %s for reading display_name, creating default" % DISPLAY_NAME_FILE)
_store_display_name()
display_name_file.close()
return _display_name
func _store_display_name():
var display_name_file = File.new()
if display_name_file.open(DISPLAY_NAME_FILE, File.WRITE) == OK:
display_name_file.store_string(display_name)
else:
print("Failed to open %s for writing display_name" % DISPLAY_NAME_FILE)
display_name_file.close()
2021-11-15 15:02:55 -06:00
2021-12-08 23:39:56 -06:00
func _send(s: String):
return websocket.get_peer(1).put_packet(s.to_utf8())
2021-11-15 15:02:55 -06:00
2021-12-08 23:39:56 -06:00
func _send_json(data: Dictionary, type=null):
if type != null: data["type"] = type
_send("json:%s" % JSON.print(data))