Work in progress

The content of this page was not yet updated for Godot 4.2 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年被標準化, 最初的目標是讓瀏覽器與伺服器建立穩定的雙向連接. 在此之前, 瀏覽器曾只支援HTTPRequests, 並不適合雙向通信.

這個協定相當簡單, 基於消息, 是一個非常強大的向瀏覽器推送通知的工具, 已經被用來實作聊天, 回合制遊戲等. 它仍使用TCP連接, 這對可靠性有好處, 但對延遲沒有好處, 所以不適合即時的應用, 比如VoIP和快節奏的遊戲(這些用例見 WebRTC).

由於它的簡單性, 廣泛的相容性以及比原始TCP連接更容易使用,WebSocket很快就開始在瀏覽器以外的地方應用, 在本地應用程式中作為與網路伺服器通信的一種手段.

Godot在本機和HTML5匯出中都支援WebSocket.

在 Godot 中使用 WebSocket

在Godot中,WebSocket通過三個主要類來實作 WebSocketClient, WebSocketServer, 和 WebSocketPeer.WebSocket的實作與高級多人遊戲相容. 更多細節請參見 high-level multiplayer 一節.

警告

當匯出到 Android 時,在匯出專案或使用一鍵部署之前,確保在 Android 匯出預設中啟用 INTERNET 許可權。否則,任何形式的網路通信都會被 Android 系統阻止。

最小使用者端範例

本範例將向您展示如何建立與遠端伺服器的 WebSocket 連接, 以及如何發送和接收資料.

extends Node

# The URL we will connect to
export var websocket_url = "wss://libwebsockets.org"

# Our WebSocketClient instance
var _client = WebSocketClient.new()

func _ready():
    # Connect base signals to get notified of connection open, close, and errors.
    _client.connection_closed.connect(_closed)
    _client.connection_error.connect(_closed)
    _client.connection_established.connect(_connected)
    # This signal is emitted when not using the Multiplayer API every time
    # a full packet is received.
    # Alternatively, you could check get_peer(1).get_available_packets() in a loop.
    _client.data_received.connect(_on_data)

    # Initiate connection to the given URL.
    var err = _client.connect_to_url(websocket_url, ["lws-mirror-protocol"])
    if err != OK:
        print("Unable to connect")
        set_process(false)

func _closed(was_clean = false):
    # was_clean will tell you if the disconnection was correctly notified
    # by the remote peer before closing the socket.
    print("Closed, clean: ", was_clean)
    set_process(false)

func _connected(proto = ""):
    # This is called on connection, "proto" will be the selected WebSocket
    # sub-protocol (which is optional)
    print("Connected with protocol: ", proto)
    # You MUST always use get_peer(1).put_packet to send data to server,
    # and not put_packet directly when not using the MultiplayerAPI.
    _client.get_peer(1).put_packet("Test packet".to_utf8())

func _on_data():
    # Print the received packet, you MUST always use get_peer(1).get_packet
    # to receive data from server, and not get_packet directly when not
    # using the MultiplayerAPI.
    print("Got data from server: ", _client.get_peer(1).get_packet().get_string_from_utf8())

func _process(delta):
    # Call this in _process or _physics_process. Data transfer, and signals
    # emission will only happen when calling this function.
    _client.poll()

這將列印:

Connected with protocol:
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 demo projectsnetworking/websocket_chatnetworking/websocket_multiplayer 有一個更高級的聊天演示demo, 可以選擇使用多人中級抽象和高級多人演示demo.