AutopatcherServerTest_MySQL.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. // Common includes
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include "Kbhit.h"
  14. #include "GetTime.h"
  15. #include "RakPeerInterface.h"
  16. #include "MessageIdentifiers.h"
  17. #include "BitStream.h"
  18. #include "StringCompressor.h"
  19. #include "FileListTransfer.h"
  20. #include "FileList.h" // FLP_Printf
  21. #include "AutopatcherServer.h"
  22. #include "AutopatcherMySQLRepository.h"
  23. #include "PacketizedTCP.h"
  24. #include "Gets.h"
  25. #ifdef _WIN32
  26. #include "WindowsIncludes.h" // Sleep
  27. #else
  28. #include <unistd.h> // usleep
  29. #endif
  30. #define USE_TCP
  31. #define LISTEN_PORT 60000
  32. #define MAX_INCOMING_CONNECTIONS 128
  33. int main(int argc, char **argv)
  34. {
  35. // Avoids the Error: Got a packet bigger than 'max_allowed_packet' bytes
  36. printf("Important: Requires that you first set the DB schema and the max packet size on the server.\n");
  37. printf("See DependentExtensions/AutopatcherMySQLRepository/readme.txt\n");
  38. // // MySQL is extremely slow in AutopatcherMySQLRepository::GetFilePart
  39. printf("WARNING: MySQL is an order of magnitude slower than PostgreSQL.\nRecommended you use AutopatcherServer_PostgreSQL instead.");
  40. printf("Server starting... ");
  41. RakNet::AutopatcherServer autopatcherServer;
  42. // RakNet::FLP_Printf progressIndicator;
  43. RakNet::FileListTransfer fileListTransfer;
  44. // So only one thread runs per connection, we create an array of connection objects, and tell the autopatcher server to use one thread per item
  45. static const int workerThreadCount=4; // Used for checking patches only
  46. static const int sqlConnectionObjectCount=32; // Used for both checking patches and downloading
  47. RakNet::AutopatcherMySQLRepository connectionObject[sqlConnectionObjectCount];
  48. RakNet::AutopatcherRepositoryInterface *connectionObjectAddresses[sqlConnectionObjectCount];
  49. for (int i=0; i < sqlConnectionObjectCount; i++)
  50. connectionObjectAddresses[i]=&connectionObject[i];
  51. // fileListTransfer.AddCallback(&progressIndicator);
  52. autopatcherServer.SetFileListTransferPlugin(&fileListTransfer);
  53. // MySQL is extremely slow in AutopatcherMySQLRepository::GetFilePart so running tho incremental reads in a thread allows multiple concurrent users to read
  54. // Without this, only one user would be sent files at a time basically
  55. fileListTransfer.StartIncrementalReadThreads(sqlConnectionObjectCount);
  56. autopatcherServer.SetMaxConurrentUsers(MAX_INCOMING_CONNECTIONS); // More users than this get queued up
  57. RakNet::AutopatcherServerLoadNotifier_Printf loadNotifier;
  58. autopatcherServer.SetLoadManagementCallback(&loadNotifier);
  59. #ifdef USE_TCP
  60. RakNet::PacketizedTCP packetizedTCP;
  61. if (packetizedTCP.Start(LISTEN_PORT,MAX_INCOMING_CONNECTIONS)==false)
  62. {
  63. printf("Failed to start TCP. Is the port already in use?");
  64. return 1;
  65. }
  66. packetizedTCP.AttachPlugin(&autopatcherServer);
  67. packetizedTCP.AttachPlugin(&fileListTransfer);
  68. #else
  69. RakNet::RakPeerInterface *rakPeer;
  70. rakPeer = RakNet::RakPeerInterface::GetInstance();
  71. RakNet::SocketDescriptor socketDescriptor(LISTEN_PORT,0);
  72. rakPeer->Startup(MAX_INCOMING_CONNECTIONS,&socketDescriptor, 1);
  73. rakPeer->SetMaximumIncomingConnections(MAX_INCOMING_CONNECTIONS);
  74. rakPeer->AttachPlugin(&autopatcherServer);
  75. rakPeer->AttachPlugin(&fileListTransfer);
  76. #endif
  77. printf("started.\n");
  78. printf("Enter database password:\n");
  79. char password[128];
  80. char username[256];
  81. strcpy(username, "root");
  82. Gets(password,sizeof(password));
  83. if (password[0]==0)
  84. strcpy(password,"aaaa");
  85. char db[256];
  86. printf("Enter DB schema: ");
  87. // To create the schema, go to the command line client and type create schema autopatcher;
  88. // You also have to add
  89. // max_allowed_packet=128M
  90. // Where 128 is the maximum size file in megabytes you'll ever add
  91. // to MySQL\MySQL Server 5.1\my.ini in the [mysqld] section
  92. // Be sure to restart the service after doing so
  93. Gets(db,sizeof(db));
  94. if (db[0]==0)
  95. strcpy(db,"autopatcher");
  96. for (int conIdx=0; conIdx < sqlConnectionObjectCount; conIdx++)
  97. {
  98. if (!connectionObject[conIdx].Connect("localhost", username, password, db, 0, NULL, 0))
  99. {
  100. printf("Database connection failed.\n");
  101. return 1;
  102. }
  103. }
  104. printf("Database connection suceeded.\n");
  105. printf("Starting threads\n");
  106. autopatcherServer.StartThreads(workerThreadCount, sqlConnectionObjectCount, connectionObjectAddresses);
  107. printf("System ready for connections\n");
  108. printf("(D)rop database\n(C)reate database.\n(A)dd application\n(U)pdate revision.\n(R)emove application\n(Q)uit\n");
  109. char ch;
  110. RakNet::Packet *p;
  111. while (1)
  112. {
  113. #ifdef USE_TCP
  114. RakNet::SystemAddress notificationAddress;
  115. notificationAddress=packetizedTCP.HasCompletedConnectionAttempt();
  116. if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  117. printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
  118. notificationAddress=packetizedTCP.HasNewIncomingConnection();
  119. if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  120. printf("ID_NEW_INCOMING_CONNECTION\n");
  121. notificationAddress=packetizedTCP.HasLostConnection();
  122. if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS)
  123. printf("ID_CONNECTION_LOST\n");
  124. p=packetizedTCP.Receive();
  125. while (p)
  126. {
  127. packetizedTCP.DeallocatePacket(p);
  128. p=packetizedTCP.Receive();
  129. }
  130. #else
  131. p=rakPeer->Receive();
  132. while (p)
  133. {
  134. if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
  135. printf("ID_NEW_INCOMING_CONNECTION\n");
  136. else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION)
  137. printf("ID_DISCONNECTION_NOTIFICATION\n");
  138. else if (p->data[0]==ID_CONNECTION_LOST)
  139. printf("ID_CONNECTION_LOST\n");
  140. rakPeer->DeallocatePacket(p);
  141. p=rakPeer->Receive();
  142. }
  143. #endif
  144. if (kbhit())
  145. {
  146. ch=getch();
  147. if (ch=='q')
  148. break;
  149. else if (ch=='c')
  150. {
  151. if (connectionObject[0].CreateAutopatcherTables()==false)
  152. printf("Error: %s\n", connectionObject[0].GetLastError());
  153. else
  154. printf("Created\n");
  155. }
  156. else if (ch=='d')
  157. {
  158. if (connectionObject[0].DestroyAutopatcherTables()==false)
  159. printf("Error: %s\n", connectionObject[0].GetLastError());
  160. else
  161. printf("Destroyed\n");
  162. }
  163. else if (ch=='a')
  164. {
  165. printf("Enter application name to add: ");
  166. char appName[512];
  167. Gets(appName,sizeof(appName));
  168. if (appName[0]==0)
  169. strcpy(appName, "TestApp");
  170. if (connectionObject[0].AddApplication(appName, username)==false)
  171. printf("Error: %s\n", connectionObject[0].GetLastError());
  172. else
  173. printf("Done\n");
  174. }
  175. else if (ch=='r')
  176. {
  177. printf("Enter application name to remove: ");
  178. char appName[512];
  179. Gets(appName,sizeof(appName));
  180. if (appName[0]==0)
  181. strcpy(appName, "TestApp");
  182. if (connectionObject[0].RemoveApplication(appName)==false)
  183. printf("Error: %s\n", connectionObject[0].GetLastError());
  184. else
  185. printf("Done\n");
  186. }
  187. else if (ch=='u')
  188. {
  189. printf("Enter application name: ");
  190. char appName[512];
  191. Gets(appName,sizeof(appName));
  192. if (appName[0]==0)
  193. strcpy(appName, "TestApp");
  194. printf("Enter application directory: ");
  195. char appDir[512];
  196. Gets(appDir,sizeof(appName));
  197. if (appDir[0]==0)
  198. strcpy(appDir, "C:/temp");
  199. if (connectionObject[0].UpdateApplicationFiles(appName, appDir, username, 0)==false)
  200. {
  201. printf("Error: %s\n", connectionObject[0].GetLastError());
  202. }
  203. else
  204. {
  205. printf("Update success.\n");
  206. }
  207. }
  208. }
  209. RakSleep(30);
  210. }
  211. #ifdef USE_TCP
  212. packetizedTCP.Stop();
  213. #else
  214. RakNet::RakPeerInterface::DestroyInstance(rakPeer);
  215. #endif
  216. }
粤ICP备19079148号