Network.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //
  2. // Copyright (c) 2008-2020 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/HashSet.h"
  24. #include "../Core/Object.h"
  25. #include "../IO/VectorBuffer.h"
  26. #include "../Network/Connection.h"
  27. #include "WS/WSPacket.h"
  28. namespace Urho3D
  29. {
  30. class HttpRequest;
  31. class MemoryBuffer;
  32. class Scene;
  33. class WSClient;
  34. class WSConnection;
  35. class WSServer;
  36. /// %Network subsystem. Manages client-server communications using the UDP protocol.
  37. class URHO3D_API Network : public Object
  38. {
  39. URHO3D_OBJECT(Network, Object);
  40. friend WSClient;
  41. friend WSServer;
  42. public:
  43. /// Construct.
  44. explicit Network(Context* context);
  45. /// Destruct.
  46. ~Network() override;
  47. #ifndef __EMSCRIPTEN__
  48. /// Handle an inbound message.
  49. void HandleMessage(const SLNet::AddressOrGUID& source, int packetID, int msgID, const char* data, size_t numBytes);
  50. /// Handle new UDP client connection.
  51. void NewConnectionEstablished(const SLNet::AddressOrGUID& connection);
  52. /// Handle a client disconnection.
  53. void ClientDisconnected(const SLNet::AddressOrGUID& connection);
  54. #endif
  55. // Handle new client connection
  56. void NewConnectionEstablished(const SharedPtr<Connection> newConnection);
  57. /// Handle new Websockets client connection.
  58. void NewConnectionEstablished(const WSConnection& ws);
  59. /// Handle a client disconnection.
  60. void ClientDisconnected(const WSConnection& ws);
  61. /// Set the data that will be used for a reply to attempts at host discovery on LAN/subnet.
  62. void SetDiscoveryBeacon(const VariantMap& data);
  63. /// Scan the LAN/subnet for available hosts.
  64. void DiscoverHosts(unsigned port);
  65. /// Set password for the client/server communcation.
  66. void SetPassword(const String& password);
  67. /// Set NAT server information.
  68. void SetNATServerInfo(const String& address, unsigned short port);
  69. /// Connect to a server using UDP protocol. Return true if connection process successfully started.
  70. bool Connect(const String& address, unsigned short port, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
  71. /// Connect to a server using Websockets connection. Return true if connection process successfully started.
  72. bool ConnectWS(const String& address, unsigned short port, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
  73. /// Return a client or server connection by Websocket connection, or null if none exist.
  74. Connection* GetConnection(const WSConnection& ws) const;
  75. /// Handle server connection.
  76. void OnServerConnected(const WSConnection& ws);
  77. /// Disconnect the connection to the server. If wait time is non-zero, will block while waiting for disconnect to finish.
  78. void Disconnect(int waitMSec = 0);
  79. /// Start a server on a port using UDP protocol. Return true if successful.
  80. bool StartServer(unsigned short port, unsigned int maxConnections = 128);
  81. /// Start a server on a port using Websockets protocol. Return true if successful.
  82. bool StartWSServer(unsigned short port, unsigned int maxConnections = 128);
  83. /// Stop the server.
  84. void StopServer();
  85. /// Stop the server.
  86. void StopUDPServer();
  87. /// Stop the server.
  88. void StopWSServer();
  89. /// Start NAT punchtrough client to allow remote connections.
  90. void StartNATClient();
  91. /// Get local server GUID.
  92. /// @property{get_guid}
  93. const String& GetGUID() const { return guid_; }
  94. /// Attempt to connect to NAT server.
  95. void AttemptNATPunchtrough(const String& guid, Scene* scene, const VariantMap& identity = Variant::emptyVariantMap);
  96. /// Broadcast a message with content ID to all client connections.
  97. void BroadcastMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID = 0);
  98. /// Broadcast a message with content ID to all client connections.
  99. void BroadcastMessage(int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes, unsigned contentID = 0);
  100. /// Broadcast a remote event to all client connections.
  101. void BroadcastRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  102. /// Broadcast a remote event to all client connections in a specific scene.
  103. void BroadcastRemoteEvent(Scene* scene, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  104. /// Broadcast a remote event with the specified node as a sender. Is sent to all client connections in the node's scene.
  105. void BroadcastRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  106. /// Set network update FPS.
  107. /// @property
  108. void SetUpdateFps(int fps);
  109. /// Set simulated latency in milliseconds. This adds a fixed delay before sending each packet.
  110. /// @property
  111. void SetSimulatedLatency(int ms);
  112. /// Set simulated packet loss probability between 0.0 - 1.0.
  113. /// @property
  114. void SetSimulatedPacketLoss(float probability);
  115. /// Register a remote event as allowed to be received. There is also a fixed blacklist of events that can not be allowed in any case, such as ConsoleCommand.
  116. void RegisterRemoteEvent(StringHash eventType);
  117. /// Unregister a remote event as allowed to received.
  118. void UnregisterRemoteEvent(StringHash eventType);
  119. /// Unregister all remote events.
  120. void UnregisterAllRemoteEvents();
  121. /// Set the package download cache directory.
  122. /// @property
  123. void SetPackageCacheDir(const String& path);
  124. /// Trigger all client connections in the specified scene to download a package file from the server. Can be used to download additional resource packages when clients are already joined in the scene. The package must have been added as a requirement to the scene, or else the eventual download will fail.
  125. void SendPackageToClients(Scene* scene, PackageFile* package);
  126. /// Perform an HTTP request to the specified URL. Empty verb defaults to a GET request. Return a request object which can be used to read the response data.
  127. SharedPtr<HttpRequest> MakeHttpRequest(const String& url, const String& verb = String::EMPTY, const Vector<String>& headers = Vector<String>(), const String& postData = String::EMPTY);
  128. /// Ban specific IP addresses.
  129. void BanAddress(const String& address);
  130. /// Return network update FPS.
  131. /// @property
  132. int GetUpdateFps() const { return updateFps_; }
  133. /// Return simulated latency in milliseconds.
  134. /// @property
  135. int GetSimulatedLatency() const { return simulatedLatency_; }
  136. /// Return simulated packet loss probability.
  137. /// @property
  138. float GetSimulatedPacketLoss() const { return simulatedPacketLoss_; }
  139. #ifndef __EMSCRIPTEN__
  140. /// Return a client or server connection by RakNet connection address, or null if none exist.
  141. Connection* GetConnection(const SLNet::AddressOrGUID& connection) const;
  142. #endif
  143. /// Return the connection to the server. Null if not connected.
  144. /// @property
  145. Connection* GetServerConnection() const;
  146. /// Return all client connections.
  147. /// @property
  148. Vector<SharedPtr<Connection> > GetClientConnections() const;
  149. /// Return whether the server is running.
  150. /// @property
  151. bool IsServerRunning() const;
  152. /// Return whether the UDP server is running.
  153. bool IsUDPServerRunning() const;
  154. /// Return whether the websockets server is running.
  155. bool IsWSServerRunning() const;
  156. /// Return whether a remote event is allowed to be received.
  157. bool CheckRemoteEvent(StringHash eventType) const;
  158. /// Return the package download cache directory.
  159. /// @property
  160. const String& GetPackageCacheDir() const { return packageCacheDir_; }
  161. /// Process incoming messages from connections. Called by HandleBeginFrame.
  162. void Update(float timeStep);
  163. /// Send outgoing messages after frame logic. Called by HandleRenderUpdate.
  164. void PostUpdate(float timeStep);
  165. private:
  166. /// Handle begin frame event.
  167. void HandleBeginFrame(StringHash eventType, VariantMap& eventData);
  168. /// Handle render update frame event.
  169. void HandleRenderUpdate(StringHash eventType, VariantMap& eventData);
  170. #ifndef __EMSCRIPTEN__
  171. /// Handle server connection.
  172. void OnServerConnected(const SLNet::AddressOrGUID& address);
  173. /// Handle UDP server disconnection.
  174. void OnServerDisconnected(const SLNet::AddressOrGUID& address);
  175. #endif
  176. /// Handle Websockets server disconnection.
  177. void OnServerDisconnected(const WSConnection& ws, bool failedConnect = false);
  178. /// Reconfigure network simulator parameters on all existing connections.
  179. void ConfigureNetworkSimulator();
  180. /// All incoming UDP packets are handled here.
  181. void HandleIncomingPacket(SLNet::Packet* packet, bool isServer);
  182. /// All incoming websocket packets are handled here.
  183. void HandleIncomingPacket(const WSPacket* packet, bool isServer);
  184. /// SLikeNet peer instance for server connection.
  185. SLNet::RakPeerInterface* rakPeer_;
  186. /// SLikeNet peer instance for client connection.
  187. SLNet::RakPeerInterface* rakPeerClient_;
  188. /// Client's server connection.
  189. SharedPtr<Connection> serverConnection_;
  190. #ifndef __EMSCRIPTEN__
  191. /// SLikeNet server's client connections.
  192. HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> > clientConnections_;
  193. #endif
  194. /// Websocket server's client connections.
  195. HashMap<WSConnection, SharedPtr<Connection> > websocketClientConnections_;
  196. /// Allowed remote events.
  197. HashSet<StringHash> allowedRemoteEvents_;
  198. /// Remote event fixed blacklist.
  199. HashSet<StringHash> blacklistedRemoteEvents_;
  200. /// Networked scenes.
  201. HashSet<Scene*> networkScenes_;
  202. /// Update FPS.
  203. int updateFps_;
  204. /// Simulated latency (send delay) in milliseconds.
  205. int simulatedLatency_;
  206. /// Simulated packet loss probability between 0.0 - 1.0.
  207. float simulatedPacketLoss_;
  208. /// Update time interval.
  209. float updateInterval_;
  210. /// Update time accumulator.GetConnection
  211. float updateAcc_;
  212. /// Package cache directory.
  213. String packageCacheDir_;
  214. /// Whether we started as server or not.
  215. bool isServer_;
  216. /// Server/Client password used for connecting.
  217. String password_;
  218. /// Scene which will be used for NAT punchtrough connections.
  219. Scene* scene_;
  220. /// Client identify for NAT punchtrough connections.
  221. VariantMap identity_;
  222. /// NAT punchtrough server information.
  223. SLNet::SystemAddress* natPunchServerAddress_;
  224. /// NAT punchtrough client for the server.
  225. SLNet::NatPunchthroughClient* natPunchthroughServerClient_;
  226. /// NAT punchtrough client for the client.
  227. SLNet::NatPunchthroughClient* natPunchthroughClient_;
  228. /// Remote GUID information.
  229. SLNet::RakNetGUID* remoteGUID_;
  230. /// Local server GUID.
  231. String guid_;
  232. WSServer* wsServer_;
  233. WSClient* wsClient_;
  234. };
  235. /// Register Network library objects.
  236. void URHO3D_API RegisterNetworkLibrary(Context* context);
  237. }