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.

Godot에서 WebSocket 사용하기

HTML5 및 웹소켓

WebSocket 프로토콜은 브라우저가 서버와 안정적인 양방향 연결을 생성할 수 있도록 하는 원래 목표로 2011년에 표준화되었습니다. 그 전에는 브라우저가 HTTP 요청만 지원했는데, 이는 양방향 통신에 적합하지 않았습니다.

이 프로토콜은 메시지 기반이며 브라우저에 푸시 알림을 보내는 매우 강력한 도구입니다. 채팅, 턴제 게임 등을 구현하는 데 사용되었습니다. 안정성에는 좋지만 대기 시간에는 적합하지 않은 TCP 연결을 여전히 사용하므로 VoIP 및 빠르게 진행되는 게임과 같은 실시간 애플리케이션에는 적합하지 않습니다(해당 사용 사례는 WebRTC 참조).

단순성, 폭넓은 호환성, 원시 TCP 연결보다 사용하기 쉬운 WebSocket은 브라우저 외부, 기본 애플리케이션에서 네트워크 서버와 통신하는 수단으로 확산되기 시작했습니다.

Godot는 네이티브 및 웹 내보내기 모두에서 WebSocket을 지원합니다.

Godot에서 WebSocket 사용하기

WebSocket는 Godot에서 WebSocketPeer를 통해 구현됩니다. WebSocket 구현은 높은 수준의 멀티플레이어와 호환됩니다. 자세한 사항은 높은 수준 멀티플레이어의 섹션을 참조하세요.

경고

Android로 내보낼 때 프로젝트를 내보내거나 원클릭 배포를 사용하기 전에 Android 내보내기 사전 설정에서 INTERNET 권한을 활성화해야 합니다. 그렇지 않으면 모든 종류의 네트워크 통신이 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

고급 채팅 데모

멀티플레이어 중간 수준 추상화와 고급 멀티플레이어 데모를 선택적으로 사용하는 고급 채팅 데모는 networking/websocket_chatnetworking/websocket_multiplayer 아래의 `godot 데모 프로젝트 <https://github.com/godotengine/godot-demo-projects>`_에서 사용할 수 있습니다.