websocket.rst 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. .. _doc_websocket:
  2. WebSocket
  3. =========
  4. HTML5 and WebSocket
  5. -------------------
  6. The WebSocket protocol was standardized in 2011 with the original goal of allowing browsers to create stable and bidirectional connections with a server.
  7. Before that, browsers used to only support HTTPRequests, which is not well-suited for bidirectional communication.
  8. 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).
  9. 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.
  10. Godot supports WebSocket in both native and HTML5 exports.
  11. Using WebSocket in Godot
  12. ------------------------
  13. 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 compatible with the High Level Multiplayer. See section on :ref:`high-level multiplayer <doc_high_level_multiplayer>` for more details.
  14. Minimal client example
  15. ^^^^^^^^^^^^^^^^^^^^^^
  16. This example will show you how to create a WebSocket connection to a remote server, and how to send and receive data.
  17. ::
  18. extends Node
  19. # The URL we will connect to
  20. export var websocket_url = "ws://echo.websocket.org"
  21. # Our WebSocketClient instance
  22. var _client = WebSocketClient.new()
  23. func _ready():
  24. # Connect base signals to get notified of connection open, close, and errors.
  25. _client.connect("connection_closed", self, "_closed")
  26. _client.connect("connection_error", self, "_closed")
  27. _client.connect("connection_established", self, "_connected")
  28. # This signal is emitted when not using the Multiplayer API every time
  29. # a full packet is received.
  30. # Alternatively, you could check get_peer(1).get_available_packets() in a loop.
  31. _client.connect("data_received", self, "_on_data")
  32. # Initiate connection to the given URL.
  33. var err = _client.connect_to_url(websocket_url)
  34. if err != OK:
  35. print("Unable to connect")
  36. set_process(false)
  37. func _closed(was_clean = false):
  38. # was_clean will tell you if the disconnection was correctly notified
  39. # by the remote peer before closing the socket.
  40. print("Closed, clean: ", was_clean)
  41. set_process(false)
  42. func _connected(proto = ""):
  43. # This is called on connection, "proto" will be the selected WebSocket
  44. # sub-protocol (which is optional)
  45. print("Connected with protocol: ", proto)
  46. # You MUST always use get_peer(1).put_packet to send data to server,
  47. # and not put_packet directly when not using the MultiplayerAPI.
  48. _client.get_peer(1).put_packet("Test packet".to_utf8())
  49. func _on_data():
  50. # Print the received packet, you MUST always use get_peer(1).get_packet
  51. # to receive data from server, and not get_packet directly when not
  52. # using the MultiplayerAPI.
  53. print("Got data from server: ", _client.get_peer(1).get_packet().get_string_from_utf8())
  54. func _process(delta):
  55. # Call this in _process or _physics_process. Data transfer, and signals
  56. # emission will only happen when calling this function.
  57. _client.poll()
  58. This will print:
  59. ::
  60. Connected with protocol:
  61. Got data from server: Test packet
  62. Minimal server example
  63. ^^^^^^^^^^^^^^^^^^^^^^
  64. This example will show you how to create a WebSocket server that listen for remote connections, and how to send and receive data.
  65. ::
  66. extends Node
  67. # The port we will listen to
  68. const PORT = 9080
  69. # Our WebSocketServer instance
  70. var _server = WebSocketServer.new()
  71. func _ready():
  72. # Connect base signals to get notified of new client connections,
  73. # disconnections, and disconnect requests.
  74. _server.connect("client_connected", self, "_connected")
  75. _server.connect("client_disconnected", self, "_disconnected")
  76. _server.connect("client_close_request", self, "_close_request")
  77. # This signal is emitted when not using the Multiplayer API every time a
  78. # full packet is received.
  79. # Alternatively, you could check get_peer(PEER_ID).get_available_packets()
  80. # in a loop for each connected peer.
  81. _server.connect("data_received", self, "_on_data")
  82. # Start listening on the given port.
  83. var err = _server.listen(PORT)
  84. if err != OK:
  85. print("Unable to start server")
  86. set_process(false)
  87. func _connected(id, proto):
  88. # This is called when a new peer connects, "id" will be the assigned peer id,
  89. # "proto" will be the selected WebSocket sub-protocol (which is optional)
  90. print("Client %d connected with protocol: %s" % [id, proto])
  91. func _close_request(id, code, reason):
  92. # This is called when a client notifies that it wishes to close the connection,
  93. # providing a reason string and close code.
  94. print("Client %d disconnecting with code: %d, reason: %s" % [id, code, reason])
  95. func _disconnected(id, was_clean = false):
  96. # This is called when a client disconnects, "id" will be the one of the
  97. # disconnecting client, "was_clean" will tell you if the disconnection
  98. # was correctly notified by the remote peer before closing the socket.
  99. print("Client %d disconnected, clean: %s" % [id, str(was_clean)])
  100. func _on_data(id):
  101. # Print the received packet, you MUST always use get_peer(id).get_packet to receive data,
  102. # and not get_packet directly when not using the MultiplayerAPI.
  103. var pkt = _server.get_peer(id).get_packet()
  104. print("Got data from client %d: %s ... echoing" % [id, pkt.get_string_from_utf8()])
  105. _server.get_peer(id).put_packet(pkt)
  106. func _process(delta):
  107. # Call this in _process or _physics_process.
  108. # Data transfer, and signals emission will only happen when calling this function.
  109. _server.poll()
  110. This will print (when a client connects) something similar to this:
  111. ::
  112. Client 1348090059 connected with protocol: selected-protocol
  113. Got data from client 1348090059: Test packet ... echoing
  114. Advanced chat demo
  115. ^^^^^^^^^^^^^^^^^^
  116. 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`.