capi_websocketserver.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**
  2. * Copyright (c) 2021 Paul-Louis Ageneau
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  7. */
  8. #include "test.hpp"
  9. #include <rtc/rtc.h>
  10. #if RTC_ENABLE_WEBSOCKET
  11. #include <cstdio>
  12. #include <cstdlib>
  13. #include <cstring>
  14. #ifdef _WIN32
  15. #include <windows.h>
  16. static void sleep(unsigned int secs) { Sleep(secs * 1000); }
  17. #else
  18. #include <unistd.h> // for sleep
  19. #endif
  20. static const char *MESSAGE = "Hello, this is a C API WebSocket test!";
  21. static bool success = false;
  22. static bool failed = false;
  23. static int wsclient = -1;
  24. static void RTC_API openCallback(int ws, void *ptr) {
  25. printf("WebSocket: Connection open\n");
  26. if (rtcSendMessage(ws, MESSAGE, -1) < 0) { // negative size indicates a null-terminated string
  27. fprintf(stderr, "rtcSendMessage failed\n");
  28. failed = true;
  29. return;
  30. }
  31. }
  32. static void RTC_API closedCallback(int ws, void *ptr) { printf("WebSocket: Connection closed"); }
  33. static void RTC_API messageCallback(int ws, const char *message, int size, void *ptr) {
  34. if (size < 0 && strcmp(message, MESSAGE) == 0) {
  35. printf("WebSocket: Received expected message\n");
  36. success = true;
  37. } else {
  38. fprintf(stderr, "Received UNEXPECTED message\n");
  39. failed = true;
  40. }
  41. }
  42. static void RTC_API serverOpenCallback(int ws, void *ptr) {
  43. printf("WebSocketServer: Client connection open\n");
  44. char path[256];
  45. if (rtcGetWebSocketPath(ws, path, 256) < 0) {
  46. fprintf(stderr, "rtcGetWebSocketPath failed\n");
  47. failed = true;
  48. return;
  49. }
  50. if (strcmp(path, "/mypath") != 0) {
  51. fprintf(stderr, "Wrong WebSocket path: %s\n", path);
  52. failed = true;
  53. }
  54. }
  55. static void RTC_API serverClosedCallback(int ws, void *ptr) {
  56. printf("WebSocketServer: Client connection closed\n");
  57. }
  58. static void RTC_API serverMessageCallback(int ws, const char *message, int size, void *ptr) {
  59. if (rtcSendMessage(ws, message, size) < 0) {
  60. fprintf(stderr, "rtcSendMessage failed\n");
  61. failed = true;
  62. }
  63. }
  64. static void RTC_API serverClientCallback(int wsserver, int ws, void *ptr) {
  65. wsclient = ws;
  66. char address[256];
  67. if (rtcGetWebSocketRemoteAddress(ws, address, 256) < 0) {
  68. fprintf(stderr, "rtcGetWebSocketRemoteAddress failed\n");
  69. failed = true;
  70. return;
  71. }
  72. printf("WebSocketServer: Received client connection from %s", address);
  73. rtcSetOpenCallback(ws, serverOpenCallback);
  74. rtcSetClosedCallback(ws, serverClosedCallback);
  75. rtcSetMessageCallback(ws, serverMessageCallback);
  76. }
  77. int test_capi_websocketserver_main() {
  78. const char *url = "wss://localhost:48081/mypath";
  79. const uint16_t port = 48081;
  80. int wsserver = -1;
  81. int ws = -1;
  82. int attempts;
  83. rtcInitLogger(RTC_LOG_DEBUG, nullptr);
  84. rtcWsServerConfiguration serverConfig;
  85. memset(&serverConfig, 0, sizeof(serverConfig));
  86. serverConfig.port = port;
  87. serverConfig.enableTls = true;
  88. // serverConfig.certificatePemFile = ...
  89. // serverConfig.keyPemFile = ...
  90. wsserver = rtcCreateWebSocketServer(&serverConfig, serverClientCallback);
  91. if (wsserver < 0)
  92. goto error;
  93. if (rtcGetWebSocketServerPort(wsserver) != int(port)) {
  94. fprintf(stderr, "rtcGetWebSocketServerPort failed\n");
  95. goto error;
  96. }
  97. rtcWsConfiguration config;
  98. memset(&config, 0, sizeof(config));
  99. config.disableTlsVerification = true;
  100. ws = rtcCreateWebSocketEx(url, &config);
  101. if (ws < 0)
  102. goto error;
  103. rtcSetOpenCallback(ws, openCallback);
  104. rtcSetClosedCallback(ws, closedCallback);
  105. rtcSetMessageCallback(ws, messageCallback);
  106. attempts = 10;
  107. while (!success && !failed && attempts--)
  108. sleep(1);
  109. if (!success || failed)
  110. goto error;
  111. rtcDeleteWebSocket(wsclient);
  112. sleep(1);
  113. rtcDeleteWebSocket(ws);
  114. sleep(1);
  115. rtcDeleteWebSocketServer(wsserver);
  116. sleep(1);
  117. printf("Success\n");
  118. return 0;
  119. error:
  120. if (wsclient >= 0)
  121. rtcDeleteWebSocket(wsclient);
  122. if (ws >= 0)
  123. rtcDeleteWebSocket(ws);
  124. if (wsserver >= 0)
  125. rtcDeleteWebSocketServer(wsserver);
  126. return -1;
  127. }
  128. #include <stdexcept>
  129. TestResult test_capi_websocketserver() {
  130. if (test_capi_websocketserver_main())
  131. return TestResult(false, "WebSocketServer test failed");
  132. return TestResult(true);
  133. }
  134. #endif