Work in progress
The content of this page was not yet updated for Godot
4.4
and may be outdated. If you know how to improve this page or you can confirm
that it's up to date, feel free to open a pull request.
WebSocket
HTML5 與 WebSocket
WebSocket 協定於 2011 年標準化,目的是讓瀏覽器能和伺服器建立穩定的雙向連線。在此之前,瀏覽器僅支援 HTTP 請求,並不適合雙向通訊。
WebSocket 以訊息為單位,適合做推播通知,也常用於聊天、回合制遊戲等。它本質上還是 TCP 連線,因此穩定但延遲高,不適合 VoIP 或即時動作遊戲(這類請見 WebRTC)。
由於 WebSocket 簡單、兼容性高又比 TCP 連線容易用,很快開始被原生 APP 採用,拿來和伺服器溝通。
Godot 在原生與 HTML5 匯出皆支援 WebSocket。
在 Godot 中使用 WebSocket
Godot 以 WebSocketPeer 提供 WebSocket 支援,並且可與高階多人 API 搭配使用。更多細節請見 高階多人連線。
警告
匯出到 Android 時,請在匯出專案或一鍵部署前,於 Android 匯出設定啟用 INTERNET 權限,否則所有網路連線都會被 Android 阻擋。
基本用戶端範例
本範例將示範如何建立 WebSocket 連線、並與遠端伺服器收發資料。
extends Node
# The URL we will connect to.
@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("Unable to connect")
set_process(false)
else:
# Wait for the socket to connect.
await get_tree().create_timer(2).timeout
# Send data.
socket.send_text("Test packet")
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():
print("Got data from server: ", socket.get_packet().get_string_from_utf8())
# 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.
這將印出類似:
Got data from server: Request served by 7811941c69e658
Got data from server: Test packet
基本伺服器範例
這個範例將示範如何建立一個 WebSocket 伺服器收聽連線,並進行資料交換。
extends Node
# The port we will listen to
const PORT = 9080
# Our WebSocketServer instance
var _server = WebSocketServer.new()
func _ready():
# Connect base signals to get notified of new client connections,
# disconnections, and disconnect requests.
_server.client_connected.connect(_connected)
_server.client_disconnected.connect(_disconnected)
_server.client_close_request.connect(_close_request)
# This signal is emitted when not using the Multiplayer API every time a
# full packet is received.
# Alternatively, you could check get_peer(PEER_ID).get_available_packets()
# in a loop for each connected peer.
_server.data_received.connect(_on_data)
# Start listening on the given port.
var err = _server.listen(PORT)
if err != OK:
print("Unable to start server")
set_process(false)
func _connected(id, proto):
# This is called when a new peer connects, "id" will be the assigned peer id,
# "proto" will be the selected WebSocket sub-protocol (which is optional)
print("Client %d connected with protocol: %s" % [id, proto])
func _close_request(id, code, reason):
# This is called when a client notifies that it wishes to close the connection,
# providing a reason string and close code.
print("Client %d disconnecting with code: %d, reason: %s" % [id, code, reason])
func _disconnected(id, was_clean = false):
# This is called when a client disconnects, "id" will be the one of the
# disconnecting client, "was_clean" will tell you if the disconnection
# was correctly notified by the remote peer before closing the socket.
print("Client %d disconnected, clean: %s" % [id, str(was_clean)])
func _on_data(id):
# Print the received packet, you MUST always use get_peer(id).get_packet to receive data,
# and not get_packet directly when not using the MultiplayerAPI.
var pkt = _server.get_peer(id).get_packet()
print("Got data from client %d: %s ... echoing" % [id, pkt.get_string_from_utf8()])
_server.get_peer(id).put_packet(pkt)
func _process(delta):
# Call this in _process or _physics_process.
# Data transfer, and signals emission will only happen when calling this function.
_server.poll()
當有用戶端連線時,將印出類似:
Client 1348090059 connected with protocol: selected-protocol
Got data from client 1348090059: Test packet ... echoing
進階聊天室範例
一個更進階的聊天範例 (其選擇性地使用中級多人連線抽象層) 以及一個高階多人連線範例,可在 godot 範例專案 中的 networking/websocket_chat 和 networking/websocket_multiplayer 下取得。