websocket.rst 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. :article_outdated: True
  2. .. _doc_websocket:
  3. WebSocket
  4. =========
  5. HTML5 and WebSocket
  6. -------------------
  7. The WebSocket protocol was standardized in 2011 with the original goal of allowing browsers to create stable and bidirectional connections with a server.
  8. Before that, browsers used to only support HTTPRequests, which is not well-suited for bidirectional communication.
  9. 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 :ref:`WebRTC <doc_webrtc>` for those use cases).
  10. 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.
  11. Godot supports WebSocket in both native and HTML5 exports.
  12. Using WebSocket in Godot
  13. ------------------------
  14. WebSocket is implemented in Godot via :ref:`WebSocketPeer <class_WebSocketPeer>`.
  15. The WebSocket implementation is compatible with the High-Level Multiplayer. See
  16. section on :ref:`high-level multiplayer <doc_high_level_multiplayer>` for more
  17. details.
  18. .. warning::
  19. When exporting to Android, make sure to enable the ``INTERNET``
  20. permission in the Android export preset before exporting the project or
  21. using one-click deploy. Otherwise, network communication of any kind will be
  22. blocked by Android.
  23. Minimal client example
  24. ^^^^^^^^^^^^^^^^^^^^^^
  25. This example will show you how to create a WebSocket connection to a remote server, and how to send and receive data.
  26. ::
  27. extends Node
  28. # The URL we will connect to.
  29. @export var websocket_url = "wss://echo.websocket.org"
  30. # Our WebSocketClient instance.
  31. var socket = WebSocketPeer.new()
  32. func _ready():
  33. # Initiate connection to the given URL.
  34. var err = socket.connect_to_url(websocket_url)
  35. if err != OK:
  36. print("Unable to connect")
  37. set_process(false)
  38. else:
  39. # Wait for the socket to connect.
  40. await get_tree().create_timer(2).timeout
  41. # Send data.
  42. socket.send_text("Test packet")
  43. func _process(_delta):
  44. # Call this in _process or _physics_process. Data transfer and state updates
  45. # will only happen when calling this function.
  46. socket.poll()
  47. # get_ready_state() tells you what state the socket is in.
  48. var state = socket.get_ready_state()
  49. # WebSocketPeer.STATE_OPEN means the socket is connected and ready
  50. # to send and receive data.
  51. if state == WebSocketPeer.STATE_OPEN:
  52. while socket.get_available_packet_count():
  53. print("Got data from server: ", socket.get_packet().get_string_from_utf8())
  54. # WebSocketPeer.STATE_CLOSING means the socket is closing.
  55. # It is important to keep polling for a clean close.
  56. elif state == WebSocketPeer.STATE_CLOSING:
  57. pass
  58. # WebSocketPeer.STATE_CLOSED means the connection has fully closed.
  59. # It is now safe to stop polling.
  60. elif state == WebSocketPeer.STATE_CLOSED:
  61. # The code will be -1 if the disconnection was not properly notified by the remote peer.
  62. var code = socket.get_close_code()
  63. print("WebSocket closed with code: %d. Clean: %s" % [code, code != -1])
  64. set_process(false) # Stop processing.
  65. This will print something similar to:
  66. ::
  67. Got data from server: Request served by 7811941c69e658
  68. Got data from server: Test packet
  69. Minimal server example
  70. ^^^^^^^^^^^^^^^^^^^^^^
  71. This example will show you how to create a WebSocket server that listens for remote connections, and how to send and receive data.
  72. ::
  73. extends Node
  74. # The port we will listen to
  75. const PORT = 9080
  76. # Our WebSocketServer instance
  77. var _server = WebSocketServer.new()
  78. func _ready():
  79. # Connect base signals to get notified of new client connections,
  80. # disconnections, and disconnect requests.
  81. _server.client_connected.connect(_connected)
  82. _server.client_disconnected.connect(_disconnected)
  83. _server.client_close_request.connect(_close_request)
  84. # This signal is emitted when not using the Multiplayer API every time a
  85. # full packet is received.
  86. # Alternatively, you could check get_peer(PEER_ID).get_available_packets()
  87. # in a loop for each connected peer.
  88. _server.data_received.connect(_on_data)
  89. # Start listening on the given port.
  90. var err = _server.listen(PORT)
  91. if err != OK:
  92. print("Unable to start server")
  93. set_process(false)
  94. func _connected(id, proto):
  95. # This is called when a new peer connects, "id" will be the assigned peer id,
  96. # "proto" will be the selected WebSocket sub-protocol (which is optional)
  97. print("Client %d connected with protocol: %s" % [id, proto])
  98. func _close_request(id, code, reason):
  99. # This is called when a client notifies that it wishes to close the connection,
  100. # providing a reason string and close code.
  101. print("Client %d disconnecting with code: %d, reason: %s" % [id, code, reason])
  102. func _disconnected(id, was_clean = false):
  103. # This is called when a client disconnects, "id" will be the one of the
  104. # disconnecting client, "was_clean" will tell you if the disconnection
  105. # was correctly notified by the remote peer before closing the socket.
  106. print("Client %d disconnected, clean: %s" % [id, str(was_clean)])
  107. func _on_data(id):
  108. # Print the received packet, you MUST always use get_peer(id).get_packet to receive data,
  109. # and not get_packet directly when not using the MultiplayerAPI.
  110. var pkt = _server.get_peer(id).get_packet()
  111. print("Got data from client %d: %s ... echoing" % [id, pkt.get_string_from_utf8()])
  112. _server.get_peer(id).put_packet(pkt)
  113. func _process(delta):
  114. # Call this in _process or _physics_process.
  115. # Data transfer, and signals emission will only happen when calling this function.
  116. _server.poll()
  117. This will print (when a client connects) something similar to this:
  118. ::
  119. Client 1348090059 connected with protocol: selected-protocol
  120. Got data from client 1348090059: Test packet ... echoing
  121. Advanced chat demo
  122. ^^^^^^^^^^^^^^^^^^
  123. A more advanced chat demo which optionally uses the multiplayer mid-level
  124. abstraction and a high-level multiplayer demo are available in the
  125. `godot demo projects <https://github.com/godotengine/godot-demo-projects>`_
  126. under `networking/websocket_chat` and `networking/websocket_multiplayer`.