summaryrefslogtreecommitdiff
path: root/addons/gdUnit4/src/network/GdUnitTcpServer.gd
diff options
context:
space:
mode:
Diffstat (limited to 'addons/gdUnit4/src/network/GdUnitTcpServer.gd')
-rw-r--r--addons/gdUnit4/src/network/GdUnitTcpServer.gd140
1 files changed, 140 insertions, 0 deletions
diff --git a/addons/gdUnit4/src/network/GdUnitTcpServer.gd b/addons/gdUnit4/src/network/GdUnitTcpServer.gd
new file mode 100644
index 0000000..997d6e3
--- /dev/null
+++ b/addons/gdUnit4/src/network/GdUnitTcpServer.gd
@@ -0,0 +1,140 @@
+@tool
+class_name GdUnitTcpServer
+extends Node
+
+signal client_connected(client_id: int)
+signal client_disconnected(client_id: int)
+@warning_ignore("unused_signal")
+signal rpc_data(rpc_data: RPC)
+
+var _server: TCPServer
+var _server_name: String
+
+class TcpConnection extends GdUnitTcpNode:
+ var _id: int
+ var _stream: StreamPeerTCP
+
+
+ func _init(tcp_server: TCPServer) -> void:
+ _stream = tcp_server.take_connection()
+ #_stream.set_big_endian(true)
+ _id = _stream.get_instance_id()
+ rpc_send(_stream, RPCClientConnect.new().with_id(_id))
+
+
+ func _ready() -> void:
+ server().client_connected.emit(_id)
+
+
+ func close() -> void:
+ if _stream != null and _stream.get_status() == StreamPeerTCP.STATUS_CONNECTED:
+ _stream.disconnect_from_host()
+ queue_free()
+
+
+ func id() -> int:
+ return _id
+
+
+ func server() -> GdUnitTcpServer:
+ return get_parent()
+
+
+ func _process(_delta: float) -> void:
+ if _stream == null or _stream.get_status() != StreamPeerTCP.STATUS_CONNECTED:
+ return
+ receive_packages(_stream, func(rpc_data: RPC) -> void:
+ server().rpc_data.emit(rpc_data)
+ # is client disconnecting we close the server after a timeout of 1 second
+ if rpc_data is RPCClientDisconnect:
+ close()
+ )
+
+
+ func disconnect_from_server() -> void:
+ if _stream == null or _stream.get_status() != StreamPeerTCP.STATUS_CONNECTED:
+ return
+ rpc_send(_stream, RPCClientDisconnect.new().with_id(_id))
+
+
+ func console(_value: Variant) -> void:
+ #print_debug("TCP Server: ", value)
+ pass
+
+
+func _init(server_name := "GdUnit4 TCP Server") -> void:
+ _server_name = server_name
+ GdUnitSignals.instance().gdunit_test_session_terminate.connect(func() -> void:
+ for connection in get_children():
+ if connection is TcpConnection:
+ (connection as TcpConnection).disconnect_from_server()
+ )
+
+
+func _ready() -> void:
+ _server = TCPServer.new()
+ client_connected.connect(_on_client_connected)
+ client_disconnected.connect(_on_client_disconnected)
+
+
+func _notification(what: int) -> void:
+ if what == NOTIFICATION_PREDELETE:
+ stop()
+
+
+func start(server_port := GdUnitServerConstants.GD_TEST_SERVER_PORT) -> GdUnitResult:
+ var err := OK
+ for retry in GdUnitServerConstants.DEFAULT_SERVER_START_RETRY_TIMES:
+ err = _server.listen(server_port, "127.0.0.1")
+ if err != OK:
+ prints("GdUnit4: Can't establish server checked port: %d, Error: %s" % [server_port, error_string(err)])
+ server_port += 1
+ prints("GdUnit4: Retry (%d) ..." % retry)
+ else:
+ break
+ if err != OK:
+ if err == ERR_ALREADY_IN_USE:
+ return GdUnitResult.error("GdUnit4: Can't establish server, the server is already in use. Error: %s, " % error_string(err))
+ return GdUnitResult.error("GdUnit4: Can't establish server. Error: %s." % error_string(err))
+ console("Successfully started checked port: %d" % server_port)
+ return GdUnitResult.success(server_port)
+
+
+func stop() -> void:
+ if _server:
+ _server.stop()
+ for connection in get_children():
+ if connection is TcpConnection:
+ @warning_ignore("unsafe_method_access")
+ connection.close()
+ remove_child(connection)
+ _server = null
+
+
+func disconnect_client(client_id: int) -> void:
+ client_disconnected.emit(client_id)
+
+
+func _process(_delta: float) -> void:
+ if _server != null and not _server.is_listening():
+ return
+ # check if connection is ready to be used
+ if _server != null and _server.is_connection_available():
+ add_child(TcpConnection.new(_server))
+
+
+func _on_client_connected(client_id: int) -> void:
+ console("Client connected %d" % client_id)
+
+
+func _on_client_disconnected(client_id: int) -> void:
+ for connection in get_children():
+ @warning_ignore("unsafe_method_access")
+ if connection is TcpConnection and connection.id() == client_id:
+ @warning_ignore("unsafe_method_access")
+ connection.close()
+ remove_child(connection)
+
+
+func console(value: Variant) -> void:
+ print(_server_name, ": ", value)