Bladeren bron

Add minimal websocket tutorial.

Fabio Alessandrelli 6 jaren geleden
bovenliggende
commit
ca1ce9c710
2 gewijzigde bestanden met toevoegingen van 156 en 0 verwijderingen
  1. 1 0
      tutorials/networking/index.rst
  2. 155 0
      tutorials/networking/websocket.rst

+ 1 - 0
tutorials/networking/index.rst

@@ -9,4 +9,5 @@ Networking
    http_request_class
    http_client_class
    ssl_certificates
+   websocket
    webrtc

+ 155 - 0
tutorials/networking/websocket.rst

@@ -0,0 +1,155 @@
+.. _doc_websocket:
+
+WebSocket
+=========
+
+HTML5 and WebSocket
+-------------------
+
+The WebSocket protocol was standardized in 2011 with the original goal of allowing browsers to create stable and bidirectional connections with a server.
+Before that, browsers used to only suppport HTTPRequests, which is not well suited for bidirectional communication.
+
+The protocol is quite simple, 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 :ref:`WebRTC <doc_webrtc>` for those use cases).
+
+Due to its simplicity, its wide compatibility, and being easier to use than a raw TCP connection, WebSocket soon started to spread outside the browsers, in native applications as a mean to communicate with network servers.
+
+Godot supports WebSocket in both native and HTML5 exports.
+
+Using WebSocket in Godot
+------------------------
+
+WebSocket is implemented in Godot via three main classes :ref:`WebSocketClient <class_WebSocketClient>`, :ref:`WebSocketServer <class_WebSocketServer>`, and :ref:`WebSocketPeer <class_WebSocketPeer>`. The WebSocket implementation is compatibile with the High Level Multiplayer. See section on :ref:`high-level multiplayer <doc_high_level_multiplayer>` for more details.
+
+Minimal client example
+^^^^^^^^^^^^^^^^^^^^^^
+
+This example will show you how to create a WebSocket connection to a remote server, and how to send and receive data.
+
+::
+
+    extends Node
+    
+    # The URL we will connect to
+    export var websocket_url = "ws://echo.websocket.org"
+    
+    # Our WebSocketClient instance
+    var _client = WebSocketClient.new()
+
+    func _ready():
+        # Connect base signals to get notified of connection open, close, and errors.
+        _client.connect("connection_closed", self, "_closed")
+        _client.connect("connection_error", self, "_closed")
+        _client.connect("connection_established", self, "_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.connect("data_received", self, "_on_data")
+    
+        # Initiate connection to the given URL.
+        var err = _client.connect_to_url(websocket_url)
+        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()
+
+This will print:
+
+::
+
+    Connected with protocol: 
+    Got data from server: Test packet
+
+Minimal server example
+^^^^^^^^^^^^^^^^^^^^^^
+
+This example will show you how to create a WebSocket server that listen for remote connecitons, and how to send and receive data.
+
+::
+
+    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.connect("client_connected", self, "_connected")
+        _server.connect("client_disconnected", self, "_disconnected")
+        _server.connect("client_close_request", self, "_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.connect("data_received", self, "_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()
+
+This will print (when a client connects) something similar to this:
+
+::
+
+    Client 1348090059 connected with protocol: selected-protocol
+    Got data from client 1348090059: Test packet ... echoing
+
+Advanced chat demo
+^^^^^^^^^^^^^^^^^^
+
+A more advanced chat demo which optionally uses the multiplayer mid-level abstraction and a high level multiplayer demo are available in the `godot demo projects <https://github.com/godotengine/godot-demo-projects>`_ under `networking/websocket_chat` and `networking/websocket_multiplayer`.