Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Використання WebSockets
HTML5 і WebSocket
Протокол WebSocket був стандартизований у 2011 році з початковою метою дозволити браузерам створювати стабільні та двонаправлені з'єднання із сервером. До цього браузери підтримували лише HTTP-запити, які не дуже добре підходили для двонаправленого зв'язку.
Цей протокол базується на повідомленнях і є дуже потужним інструментом для надсилання push-сповіщень у браузери. Він використовувався для реалізації чатів, покрокових ігор тощо. Він все ще використовує TCP-з'єднання, що добре для надійності, але не для затримки, тому він не підходить для програм реального часу, таких як VoIP та швидкі ігри (див. WebRTC для цих випадків використання).
Завдяки своїй простоті, широкій сумісності та простішому використанню, ніж звичайне TCP-з'єднання, WebSocket почав поширюватися за межі браузерів, у нативних додатках як засіб зв'язку з мережевими серверами.
Godot підтримує WebSocket як у нативному, так і в веб-експорті.
Використання WebSocket в Godot
WebSocket реалізовано в Godot через WebSocketPeer. Реалізація WebSocket сумісна з багатокористувацькою іграшкою високого рівня. Перегляньте розділ про high-level multiplayer для отримання додаткової інформації.
Попередження
Під час експорту в Android обов’язково ввімкніть дозвіл INTERNET у попередньо налаштованих експортах Android, перш ніж експортувати проект, або використовувати розгортання одним клацанням мишки. Інакше Android заблокує будь-який мережевий зв’язок.
Мінімальний приклад клієнта
Цей приклад покаже вам, як створити з’єднання WebSocket з віддаленим сервером, а також як надсилати та отримувати дані.
extends Node
# The URL we will connect to.
# Use "ws://localhost:9080" if testing with the minimal server example below.
# `wss://` is used for secure connections,
# while `ws://` is used for plain text (insecure) connections.
@export var websocket_url = "wss://echo.websocket.org"
# Our WebSocketClient instance.
var socket = WebSocketPeer.new()
func _ready():
# Initiate connection to the given URL.
var err = socket.connect_to_url(websocket_url)
if err == OK:
print("Connecting to %s..." % websocket_url)
# Wait for the socket to connect.
await get_tree().create_timer(2).timeout
# Send data.
print("> Sending test packet.")
socket.send_text("Test packet")
else:
push_error("Unable to connect.")
set_process(false)
func _process(_delta):
# Call this in `_process()` or `_physics_process()`.
# Data transfer and state updates will only happen when calling this function.
socket.poll()
# get_ready_state() tells you what state the socket is in.
var state = socket.get_ready_state()
# `WebSocketPeer.STATE_OPEN` means the socket is connected and ready
# to send and receive data.
if state == WebSocketPeer.STATE_OPEN:
while socket.get_available_packet_count():
var packet = socket.get_packet()
if socket.was_string_packet():
var packet_text = packet.get_string_from_utf8()
print("< Got text data from server: %s" % packet_text)
else:
print("< Got binary data from server: %d bytes" % packet.size())
# `WebSocketPeer.STATE_CLOSING` means the socket is closing.
# It is important to keep polling for a clean close.
elif state == WebSocketPeer.STATE_CLOSING:
pass
# `WebSocketPeer.STATE_CLOSED` means the connection has fully closed.
# It is now safe to stop polling.
elif state == WebSocketPeer.STATE_CLOSED:
# The code will be `-1` if the disconnection was not properly notified by the remote peer.
var code = socket.get_close_code()
print("WebSocket closed with code: %d. Clean: %s" % [code, code != -1])
set_process(false) # Stop processing.
Це надрукує щось подібне до:
Connecting to wss://echo.websocket.org...
< Got text data from server: Request served by 7811941c69e658
> Sending test packet.
< Got text data from server: Test packet
Мінімальний приклад сервера
Цей приклад покаже вам, як створити сервер WebSocket, який прослуховує віддалені з’єднання, а також як надсилати та отримувати дані.
extends Node
# The port we will listen to.
const PORT = 9080
# Our TCP Server instance.
var _tcp_server = TCPServer.new()
# Our connected peers list.
var _peers: Dictionary[int, WebSocketPeer] = {}
var last_peer_id := 1
func _ready():
# Start listening on the given port.
var err = _tcp_server.listen(PORT)
if err == OK:
print("Server started.")
else:
push_error("Unable to start server.")
set_process(false)
func _process(_delta):
while _tcp_server.is_connection_available():
last_peer_id += 1
print("+ Peer %d connected." % last_peer_id)
var ws = WebSocketPeer.new()
ws.accept_stream(_tcp_server.take_connection())
_peers[last_peer_id] = ws
# Iterate over all connected peers using "keys()" so we can erase in the loop
for peer_id in _peers.keys():
var peer = _peers[peer_id]
peer.poll()
var peer_state = peer.get_ready_state()
if peer_state == WebSocketPeer.STATE_OPEN:
while peer.get_available_packet_count():
var packet = peer.get_packet()
if peer.was_string_packet():
var packet_text = packet.get_string_from_utf8()
print("< Got text data from peer %d: %s ... echoing" % [peer_id, packet_text])
# Echo the packet back.
peer.send_text(packet_text)
else:
print("< Got binary data from peer %d: %d ... echoing" % [peer_id, packet.size()])
# Echo the packet back.
peer.send(packet)
elif peer_state == WebSocketPeer.STATE_CLOSED:
# Remove the disconnected peer.
_peers.erase(peer_id)
var code = peer.get_close_code()
var reason = peer.get_close_reason()
print("- Peer %s closed with code: %d, reason %s. Clean: %s" % [peer_id, code, reason, code != -1])
Коли клієнт підключиться, це виведе щось подібне до цього:
Server started.
+ Peer 2 connected.
< Got text data from peer 2: Test packet ... echoing
Розширена демонстрація чату
Досконаліша демонстрація чату, яка додатково використовує абстракцію середнього рівня для кількох гравців, і демонстраційна версія для кількох гравців високого рівня доступні в демо-проектах godot у розділі networking/websocket_chat і networking/websocket_multiplayer.