WebSockCallbacks.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include <assert.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include "WebSockCallbacks.h"
  5. #ifdef _WIN32
  6. #include <Windows.h>
  7. typedef HANDLE pthread_mutex_t;
  8. static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) {
  9. unused = NULL;
  10. *mutex = CreateMutex(NULL, FALSE, NULL);
  11. return *mutex == NULL ? -1 : 0;
  12. }
  13. static int pthread_mutex_destroy(pthread_mutex_t *mutex) {
  14. return CloseHandle(*mutex) == 0 ? -1 : 0;
  15. }
  16. static int pthread_mutex_lock(pthread_mutex_t *mutex) {
  17. return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0? 0 : -1;
  18. }
  19. static int pthread_mutex_unlock(pthread_mutex_t *mutex) {
  20. return ReleaseMutex(*mutex) == 0 ? -1 : 0;
  21. }
  22. #define mg_sleep(x) Sleep(x)
  23. #else
  24. #include <unistd.h>
  25. #include <pthread.h>
  26. #define mg_sleep(x) usleep((x) * 1000)
  27. #endif
  28. typedef struct tWebSockInfo {
  29. int webSockState;
  30. unsigned long initId;
  31. struct mg_connection *conn;
  32. } tWebSockInfo;
  33. static pthread_mutex_t sMutex;
  34. #define MAX_NUM_OF_WEBSOCKS (256)
  35. static tWebSockInfo *socketList[MAX_NUM_OF_WEBSOCKS];
  36. static void send_to_all_websockets(const char * data, int data_len) {
  37. int i;
  38. for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
  39. if (socketList[i] && (socketList[i]->webSockState==2)) {
  40. mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, data, data_len);
  41. }
  42. }
  43. }
  44. void websocket_ready_handler(struct mg_connection *conn) {
  45. int i;
  46. struct mg_request_info * rq = mg_get_request_info(conn);
  47. tWebSockInfo * wsock = malloc(sizeof(tWebSockInfo));
  48. assert(wsock);
  49. wsock->webSockState = 0;
  50. rq->conn_data = wsock;
  51. pthread_mutex_lock(&sMutex);
  52. for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
  53. if (0==socketList[i]) {
  54. socketList[i] = wsock;
  55. wsock->conn = conn;
  56. wsock->webSockState = 1;
  57. break;
  58. }
  59. }
  60. pthread_mutex_unlock(&sMutex);
  61. }
  62. static void websocket_done(tWebSockInfo * wsock) {
  63. int i;
  64. if (wsock) {
  65. wsock->webSockState = 99;
  66. for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
  67. if (wsock==socketList[i]) {
  68. socketList[i] = 0;
  69. break;
  70. }
  71. }
  72. free(wsock);
  73. }
  74. }
  75. int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len) {
  76. struct mg_request_info * rq = mg_get_request_info(conn);
  77. tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data;
  78. char msg[128];
  79. pthread_mutex_lock(&sMutex);
  80. if (flags==136) {
  81. // close websock
  82. websocket_done(wsock);
  83. rq->conn_data = 0;
  84. pthread_mutex_unlock(&sMutex);
  85. return 1;
  86. }
  87. if ((data_len>=5) && (data_len<100) && (flags==129) || (flags==130)) {
  88. // init command
  89. if ((wsock->webSockState==1) && (!memcmp(data,"init ",5))) {
  90. char * chk;
  91. unsigned long gid;
  92. memcpy(msg,data+5,data_len-5);
  93. msg[data_len-5]=0;
  94. gid = strtoul(msg,&chk,10);
  95. wsock->initId = gid;
  96. if (gid>0 && chk!=NULL && *chk==0) {
  97. wsock->webSockState = 2;
  98. }
  99. pthread_mutex_unlock(&sMutex);
  100. return 1;
  101. }
  102. // chat message
  103. if ((wsock->webSockState==2) && (!memcmp(data,"msg ",4))) {
  104. send_to_all_websockets(data, data_len);
  105. pthread_mutex_unlock(&sMutex);
  106. return 1;
  107. }
  108. }
  109. // keep alive
  110. if ((data_len==4) && !memcmp(data,"ping",4)) {
  111. pthread_mutex_unlock(&sMutex);
  112. return 1;
  113. }
  114. pthread_mutex_unlock(&sMutex);
  115. return 0;
  116. }
  117. void connection_close_handler(struct mg_connection *conn) {
  118. struct mg_request_info * rq = mg_get_request_info(conn);
  119. tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data;
  120. pthread_mutex_lock(&sMutex);
  121. websocket_done(wsock);
  122. rq->conn_data = 0;
  123. pthread_mutex_unlock(&sMutex);
  124. }
  125. static int runLoop = 0;
  126. static void * eventMain(void * _ignored) {
  127. int i;
  128. char msg[256];
  129. runLoop = 1;
  130. while (runLoop) {
  131. time_t t = time(0);
  132. struct tm * timestr = localtime(&t);
  133. sprintf(msg,"title %s",asctime(timestr));
  134. pthread_mutex_lock(&sMutex);
  135. for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
  136. if (socketList[i] && (socketList[i]->webSockState==2)) {
  137. mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, msg, strlen(msg));
  138. }
  139. }
  140. pthread_mutex_unlock(&sMutex);
  141. mg_sleep(1000);
  142. }
  143. return _ignored;
  144. }
  145. void websock_send_broadcast(const char * data, int data_len) {
  146. char buffer[260];
  147. if (data_len<=256) {
  148. strcpy(buffer, "msg ");
  149. memcpy(buffer+4, data, data_len);
  150. pthread_mutex_lock(&sMutex);
  151. send_to_all_websockets(buffer, data_len+4);
  152. pthread_mutex_unlock(&sMutex);
  153. }
  154. }
  155. void websock_init_lib(void) {
  156. int ret;
  157. ret = pthread_mutex_init(&sMutex, 0);
  158. assert(ret==0);
  159. memset(socketList,0,sizeof(socketList));
  160. mg_start_thread(eventMain, 0);
  161. }
  162. void websock_exit_lib(void) {
  163. runLoop = 0;
  164. }