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.