Connection.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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. /// \file
  23. #pragma once
  24. #include "../Container/HashSet.h"
  25. #include "../Core/Object.h"
  26. #include "../Core/Timer.h"
  27. #include "../Input/Controls.h"
  28. #include "../IO/VectorBuffer.h"
  29. #include "../Scene/ReplicationState.h"
  30. #include "WS/WSConnection.h"
  31. namespace SLNet
  32. {
  33. class SystemAddress;
  34. struct AddressOrGUID;
  35. struct RakNetGUID;
  36. struct Packet;
  37. class NatPunchthroughClient;
  38. class RakPeerInterface;
  39. }
  40. namespace Urho3D
  41. {
  42. class File;
  43. class MemoryBuffer;
  44. class Node;
  45. class Scene;
  46. class Serializable;
  47. class PackageFile;
  48. class WSHandler;
  49. class WSConnection;
  50. /// Queued remote event.
  51. struct RemoteEvent
  52. {
  53. /// Remote sender node ID (0 if not a remote node event).
  54. unsigned senderID_;
  55. /// Event type.
  56. StringHash eventType_;
  57. /// Event data.
  58. VariantMap eventData_;
  59. /// In order flag.
  60. bool inOrder_;
  61. };
  62. /// Package file receive transfer.
  63. struct PackageDownload
  64. {
  65. /// Construct with defaults.
  66. PackageDownload();
  67. /// Destination file.
  68. SharedPtr<File> file_;
  69. /// Already received fragments.
  70. HashSet<unsigned> receivedFragments_;
  71. /// Package name.
  72. String name_;
  73. /// Total number of fragments.
  74. unsigned totalFragments_;
  75. /// Checksum.
  76. unsigned checksum_;
  77. /// Download initiated flag.
  78. bool initiated_;
  79. };
  80. /// Package file send transfer.
  81. struct PackageUpload
  82. {
  83. /// Construct with defaults.
  84. PackageUpload();
  85. /// Source file.
  86. SharedPtr<File> file_;
  87. /// Current fragment index.
  88. unsigned fragment_;
  89. /// Total number of fragments.
  90. unsigned totalFragments_;
  91. };
  92. /// Send modes for observer position/rotation. Activated by the client setting either position or rotation.
  93. enum ObserverPositionSendMode
  94. {
  95. OPSM_NONE = 0,
  96. OPSM_POSITION,
  97. OPSM_POSITION_ROTATION
  98. };
  99. /// Packet types for outgoing buffers. Outgoing messages are grouped by their type
  100. enum PacketType {
  101. PT_UNRELIABLE_UNORDERED,
  102. PT_UNRELIABLE_ORDERED,
  103. PT_RELIABLE_UNORDERED,
  104. PT_RELIABLE_ORDERED
  105. };
  106. /// %Connection to a remote network host.
  107. class URHO3D_API Connection : public Object
  108. {
  109. URHO3D_OBJECT(Connection, Object);
  110. public:
  111. /// Construct with context, RakNet connection address and Raknet peer pointer.
  112. Connection(Context* context, bool isClient, const SLNet::AddressOrGUID& address, SLNet::RakPeerInterface* peer);
  113. /// Construct with context, Websocket connection
  114. Connection(Context* context, bool isClient, const WSConnection& ws, WSHandler* wsHandler);
  115. /// Set Websocket connection information
  116. void SetWS(const WSConnection& ws);
  117. /// Get Websocket connection information
  118. const WSConnection& GetWS() const { return ws_; };
  119. /// Set Websocket handler for this connection
  120. void SetWSHandler(WSHandler* server);
  121. /// Get current Websocket handler for this connection
  122. const WSHandler* GetWSHandler() { return wsHandler_; }
  123. /// Destruct.
  124. ~Connection() override;
  125. /// Get packet type based on the message parameters
  126. PacketType GetPacketType(bool reliable, bool inOrder);
  127. /// Send a message.
  128. void SendMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID = 0);
  129. /// Send a message.
  130. void SendMessage(int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes, unsigned contentID = 0);
  131. /// Send a remote event.
  132. void SendRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  133. /// Send a remote event with the specified node as sender.
  134. void SendRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData = Variant::emptyVariantMap);
  135. /// Assign scene. On the server, this will cause the client to load it.
  136. /// @property
  137. void SetScene(Scene* newScene);
  138. /// Assign identity. Called by Network.
  139. void SetIdentity(const VariantMap& identity);
  140. /// Set new controls.
  141. void SetControls(const Controls& newControls);
  142. /// Set the observer position for interest management, to be sent to the server.
  143. /// @property
  144. void SetPosition(const Vector3& position);
  145. /// Set the observer rotation for interest management, to be sent to the server. Note: not used by the NetworkPriority component.
  146. /// @property
  147. void SetRotation(const Quaternion& rotation);
  148. /// Set the connection pending status. Called by Network.
  149. void SetConnectPending(bool connectPending);
  150. /// Set whether to log data in/out statistics.
  151. /// @property
  152. void SetLogStatistics(bool enable);
  153. /// Disconnect. If wait time is non-zero, will block while waiting for disconnect to finish.
  154. void Disconnect(int waitMSec = 0);
  155. /// Send scene update messages. Called by Network.
  156. void SendServerUpdate();
  157. /// Send latest controls from the client. Called by Network.
  158. void SendClientUpdate();
  159. /// Send queued remote events. Called by Network.
  160. void SendRemoteEvents();
  161. /// Send package files to client. Called by network.
  162. void SendPackages();
  163. /// Send out buffered messages by their type
  164. void SendBuffer(PacketType type);
  165. /// Send out all buffered messages
  166. void SendAllBuffers();
  167. /// Process pending latest data for nodes and components.
  168. void ProcessPendingLatestData();
  169. /// Process a message from the server or client. Called by Network.
  170. bool ProcessMessage(int msgID, MemoryBuffer& buffer);
  171. /// Ban this connections IP address.
  172. void Ban();
  173. /// Return the RakNet address/guid.
  174. const SLNet::AddressOrGUID& GetAddressOrGUID() const { return *address_; }
  175. /// Set the the RakNet address/guid.
  176. void SetAddressOrGUID(const SLNet::AddressOrGUID& addr);
  177. /// Return client identity.
  178. VariantMap& GetIdentity() { return identity_; }
  179. /// Return the scene used by this connection.
  180. /// @property
  181. Scene* GetScene() const;
  182. /// Return the client controls of this connection.
  183. const Controls& GetControls() const { return controls_; }
  184. /// Return the controls timestamp, sent from client to server along each control update.
  185. unsigned char GetTimeStamp() const { return timeStamp_; }
  186. /// Return the observer position sent by the client for interest management.
  187. /// @property
  188. const Vector3& GetPosition() const { return position_; }
  189. /// Return the observer rotation sent by the client for interest management.
  190. /// @property
  191. const Quaternion& GetRotation() const { return rotation_; }
  192. /// Return whether is a client connection.
  193. /// @property
  194. bool IsClient() const { return isClient_; }
  195. /// Return whether is fully connected.
  196. /// @property
  197. bool IsConnected() const;
  198. /// Return whether connection is pending.
  199. /// @property
  200. bool IsConnectPending() const { return connectPending_; }
  201. /// Return whether the scene is loaded and ready to receive server updates.
  202. /// @property
  203. bool IsSceneLoaded() const { return sceneLoaded_; }
  204. /// Return whether to log data in/out statistics.
  205. /// @property
  206. bool GetLogStatistics() const { return logStatistics_; }
  207. /// Return remote address.
  208. /// @property
  209. String GetAddress() const;
  210. /// Return remote port.
  211. /// @property
  212. unsigned short GetPort() const { return port_; }
  213. /// Return the connection's round trip time in milliseconds.
  214. /// @property
  215. float GetRoundTripTime() const;
  216. /// Return the time since last received data from the remote host in milliseconds.
  217. /// @property
  218. unsigned GetLastHeardTime() const;
  219. /// Return bytes received per second.
  220. /// @property
  221. float GetBytesInPerSec() const;
  222. /// Return bytes sent per second.
  223. /// @property
  224. float GetBytesOutPerSec() const;
  225. /// Return packets received per second.
  226. /// @property
  227. int GetPacketsInPerSec() const;
  228. /// Return packets sent per second.
  229. /// @property
  230. int GetPacketsOutPerSec() const;
  231. /// Return an address:port string.
  232. String ToString() const;
  233. /// Return number of package downloads remaining.
  234. /// @property
  235. unsigned GetNumDownloads() const;
  236. /// Return name of current package download, or empty if no downloads.
  237. /// @property
  238. const String& GetDownloadName() const;
  239. /// Return progress of current package download, or 1.0 if no downloads.
  240. /// @property
  241. float GetDownloadProgress() const;
  242. /// Trigger client connection to download a package file from the server. Can be used to download additional resource packages when client is already joined in a scene. The package must have been added as a requirement to the scene the client is joined in, or else the eventual download will fail.
  243. void SendPackageToClient(PackageFile* package);
  244. /// Set network simulation parameters. Called by Network.
  245. void ConfigureNetworkSimulator(int latencyMs, float packetLoss);
  246. /// Buffered packet size limit, when reached, packet is sent out immediately
  247. void SetPacketSizeLimit(int limit);
  248. /// Current controls.
  249. Controls controls_;
  250. /// Controls timestamp. Incremented after each sent update.
  251. unsigned char timeStamp_;
  252. /// Identity map.
  253. VariantMap identity_;
  254. private:
  255. /// Handle scene loaded event.
  256. void HandleAsyncLoadFinished(StringHash eventType, VariantMap& eventData);
  257. /// Process a LoadScene message from the server. Called by Network.
  258. void ProcessLoadScene(int msgID, MemoryBuffer& msg);
  259. /// Process a SceneChecksumError message from the server. Called by Network.
  260. void ProcessSceneChecksumError(int msgID, MemoryBuffer& msg);
  261. /// Process a scene update message from the server. Called by Network.
  262. void ProcessSceneUpdate(int msgID, MemoryBuffer& msg);
  263. /// Process package download related messages. Called by Network.
  264. void ProcessPackageDownload(int msgID, MemoryBuffer& msg);
  265. /// Process an Identity message from the client. Called by Network.
  266. void ProcessIdentity(int msgID, MemoryBuffer& msg);
  267. /// Process a Controls message from the client. Called by Network.
  268. void ProcessControls(int msgID, MemoryBuffer& msg);
  269. /// Process a SceneLoaded message from the client. Called by Network.
  270. void ProcessSceneLoaded(int msgID, MemoryBuffer& msg);
  271. /// Process a remote event message from the client or server. Called by Network.
  272. void ProcessRemoteEvent(int msgID, MemoryBuffer& msg);
  273. /// Process a node for sending a network update. Recurses to process depended on node(s) first.
  274. void ProcessNode(unsigned nodeID);
  275. /// Process a node that the client has not yet received.
  276. void ProcessNewNode(Node* node);
  277. /// Process a node that the client has already received.
  278. void ProcessExistingNode(Node* node, NodeReplicationState& nodeState);
  279. /// Process a SyncPackagesInfo message from server.
  280. void ProcessPackageInfo(int msgID, MemoryBuffer& msg);
  281. /// Process unknown message. All unknown messages are forwarded as an events
  282. void ProcessUnknownMessage(int msgID, MemoryBuffer& msg);
  283. /// Check a package list received from server and initiate package downloads as necessary. Return true on success, or false if failed to initialze downloads (cache dir not set).
  284. bool RequestNeededPackages(unsigned numPackages, MemoryBuffer& msg);
  285. /// Initiate a package download.
  286. void RequestPackage(const String& name, unsigned fileSize, unsigned checksum);
  287. /// Send an error reply for a package download.
  288. void SendPackageError(const String& name);
  289. /// Handle scene load failure on the server or client.
  290. void OnSceneLoadFailed();
  291. /// Handle a package download failure on the client.
  292. void OnPackageDownloadFailed(const String& name);
  293. /// Handle all packages loaded successfully. Also called directly on MSG_LOADSCENE if there are none.
  294. void OnPackagesReady();
  295. /// Scene.
  296. WeakPtr<Scene> scene_;
  297. /// Network replication state of the scene.
  298. SceneReplicationState sceneState_;
  299. /// Waiting or ongoing package file receive transfers.
  300. HashMap<StringHash, PackageDownload> downloads_;
  301. /// Ongoing package send transfers.
  302. HashMap<StringHash, PackageUpload> uploads_;
  303. /// Pending latest data for not yet received nodes.
  304. HashMap<unsigned, PODVector<unsigned char> > nodeLatestData_;
  305. /// Pending latest data for not yet received components.
  306. HashMap<unsigned, PODVector<unsigned char> > componentLatestData_;
  307. /// Node ID's to process during a replication update.
  308. HashSet<unsigned> nodesToProcess_;
  309. /// Reusable message buffer.
  310. VectorBuffer msg_;
  311. /// Queued remote events.
  312. Vector<RemoteEvent> remoteEvents_;
  313. /// Scene file to load once all packages (if any) have been downloaded.
  314. String sceneFileName_;
  315. /// Statistics timer.
  316. Timer statsTimer_;
  317. /// Remote endpoint port.
  318. unsigned short port_;
  319. /// Observer position for interest management.
  320. Vector3 position_;
  321. /// Observer rotation for interest management.
  322. Quaternion rotation_;
  323. /// Send mode for the observer position & rotation.
  324. ObserverPositionSendMode sendMode_;
  325. /// Client connection flag.
  326. bool isClient_;
  327. /// Connection pending flag.
  328. bool connectPending_;
  329. /// Scene loaded flag.
  330. bool sceneLoaded_;
  331. /// Show statistics flag.
  332. bool logStatistics_;
  333. /// Address of this connection.
  334. SLNet::AddressOrGUID* address_;
  335. /// Raknet peer object.
  336. SLNet::RakPeerInterface* peer_;
  337. /// Temporary variable to hold packet count in the next second, x - packets in, y - packets out.
  338. IntVector2 tempPacketCounter_;
  339. /// Packet count in the last second, x - packets in, y - packets out.
  340. IntVector2 packetCounter_;
  341. /// Packet count timer which resets every 1s.
  342. Timer packetCounterTimer_;
  343. /// Last heard timer, resets when new packet is incoming.
  344. Timer lastHeardTimer_;
  345. /// Outgoing packet buffer which can contain multiple messages
  346. HashMap<int, VectorBuffer> outgoingBuffer_;
  347. /// Outgoing packet size limit
  348. int packedMessageLimit_;
  349. /// Websocket connection
  350. WSConnection ws_;
  351. /// Websocket connection handler
  352. WSHandler* wsHandler_;
  353. };
  354. }