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...
WebSocket¶
HTML5 与 WebSocket¶
WebSocket协议在2011年被标准化, 最初的目标是让浏览器与服务器建立稳定的双向连接. 在此之前, 浏览器曾只支持HTTPRequests, 并不适合双向通信.
The protocol is message based and a very powerful tool to send push notifications to browsers, and has been used to implement chats, turn-based games, etc. It still uses a TCP connection, which is good for reliability but not for latency, so not good for real-time applications like VoIP and fast-paced games (see WebRTC for those use cases).
由于它的简单性, 广泛的兼容性以及比原始TCP连接更容易使用,WebSocket很快就开始在浏览器以外的地方应用, 在本地应用程序中作为与网络服务器通信的一种手段.
Godot在本机和HTML5导出中都支持WebSocket.
在 Godot 中使用 WebSocket¶
WebSocket is implemented in Godot via WebSocketPeer. The WebSocket implementation is compatible with the High Level Multiplayer. See section on high-level multiplayer for more details.
警告
导出到 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.
This will print something similar to:
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 demo projects 下 networking/websocket_chat 和 networking/websocket_multiplayer 有一个更高级的聊天演示demo, 可以选择使用多人中级抽象和高级多人演示demo.