瀏覽代碼

Update websocket example - use new API functions

bel 11 年之前
父節點
當前提交
56389ad023

+ 2 - 1
VS2012/ex_websocket/ex_websocket.vcxproj

@@ -86,7 +86,7 @@
       </PrecompiledHeader>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>USE_WEBSOCKET;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>USE_WEBSOCKET;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -145,6 +145,7 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="..\..\examples\websocket\WebSockCallbacks.h" />
     <ClInclude Include="..\..\include\civetweb.h" />
   </ItemGroup>
   <ItemGroup>

+ 6 - 0
VS2012/ex_websocket/ex_websocket.vcxproj.filters

@@ -18,6 +18,9 @@
     <ClInclude Include="..\..\include\civetweb.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\examples\websocket\WebSockCallbacks.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\examples\websocket\websocket.c">
@@ -26,5 +29,8 @@
     <ClCompile Include="..\..\src\civetweb.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\examples\websocket\WebSockCallbacks.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 34 - 57
examples/websocket/WebSockCallbacks.c

@@ -1,32 +1,11 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <time.h>
-#include "WebSockCallbacks.h"
-
-#ifdef __APPLE__
 #include <string.h>
-#endif
+#include "WebSockCallbacks.h"
 
 #ifdef _WIN32
 #include <Windows.h>
-typedef HANDLE pthread_mutex_t;
-static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) {
-    unused = NULL;
-    *mutex = CreateMutex(NULL, FALSE, NULL);
-    return *mutex == NULL ? -1 : 0;
-}
-
-static int pthread_mutex_destroy(pthread_mutex_t *mutex) {
-    return CloseHandle(*mutex) == 0 ? -1 : 0;
-}
-
-static int pthread_mutex_lock(pthread_mutex_t *mutex) {
-    return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0? 0 : -1;
-}
-
-static int pthread_mutex_unlock(pthread_mutex_t *mutex) {
-    return ReleaseMutex(*mutex) == 0 ? -1 : 0;
-}
 #define mg_sleep(x) Sleep(x)
 #else
 #include <unistd.h>
@@ -41,21 +20,22 @@ typedef struct tWebSockInfo {
     struct mg_connection *conn;
 } tWebSockInfo;
 
-static pthread_mutex_t sMutex;
 
 #define MAX_NUM_OF_WEBSOCKS (256)
 static tWebSockInfo *socketList[MAX_NUM_OF_WEBSOCKS];
 
 
-static void send_to_all_websockets(const char * data, int data_len) {
+static void send_to_all_websockets(struct mg_context *ctx, const char * data, int data_len) {
 
     int i;
 
+    mg_lock_context(ctx);
     for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
         if (socketList[i] && (socketList[i]->webSockState==2)) {
             mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, data, data_len);
         }
     }
+    mg_unlock_context(ctx);
 }
 
 
@@ -63,12 +43,13 @@ void websocket_ready_handler(struct mg_connection *conn) {
 
     int i;
     struct mg_request_info * rq = mg_get_request_info(conn);
+    struct mg_context * ctx = mg_get_context(conn);
     tWebSockInfo * wsock = malloc(sizeof(tWebSockInfo));
     assert(wsock);
     wsock->webSockState = 0;
     rq->conn_data = wsock;
 
-    pthread_mutex_lock(&sMutex);
+    mg_lock_context(ctx);
     for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
         if (0==socketList[i]) {
             socketList[i] = wsock;
@@ -78,11 +59,12 @@ void websocket_ready_handler(struct mg_connection *conn) {
         }
     }
     printf("\nNew websocket attached: %08lx:%u\n", rq->remote_ip, rq->remote_port);
-    pthread_mutex_unlock(&sMutex);
+    mg_unlock_context(ctx);
 }
 
 
 static void websocket_done(tWebSockInfo * wsock) {
+
     int i;
     if (wsock) {
         wsock->webSockState = 99;
@@ -99,16 +81,18 @@ static void websocket_done(tWebSockInfo * wsock) {
 
 
 int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len) {
+
     struct mg_request_info * rq = mg_get_request_info(conn);
+    struct mg_context * ctx = mg_get_context(conn);
     tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data;
     char msg[128];
 
-    pthread_mutex_lock(&sMutex);
+    mg_lock_context(ctx);
     if (flags==136) {
         // close websock
         websocket_done(wsock);
         rq->conn_data = 0;
-        pthread_mutex_unlock(&sMutex);
+        mg_unlock_context(ctx);
         return 1;
     }
     if (((data_len>=5) && (data_len<100) && (flags==129)) || (flags==130)) {
@@ -124,45 +108,48 @@ int websocket_data_handler(struct mg_connection *conn, int flags, char *data, si
             if (gid>0 && chk!=NULL && *chk==0) {
                 wsock->webSockState = 2;
             }
-            pthread_mutex_unlock(&sMutex);
+            mg_unlock_context(ctx);
             return 1;
         }
 
         // chat message
         if ((wsock->webSockState==2) && (!memcmp(data,"msg ",4))) {
-            send_to_all_websockets(data, data_len);
-            pthread_mutex_unlock(&sMutex);
+            send_to_all_websockets(ctx, data, data_len);
+            mg_unlock_context(ctx);
             return 1;
         }
     }
 
     // keep alive
     if ((data_len==4) && !memcmp(data,"ping",4)) {
-        pthread_mutex_unlock(&sMutex);
+        mg_unlock_context(ctx);
         return 1;
     }
 
-    pthread_mutex_unlock(&sMutex);
+    mg_unlock_context(ctx);
     return 0;
 }
 
 
 void connection_close_handler(struct mg_connection *conn) {
+
     struct mg_request_info * rq = mg_get_request_info(conn);
+    struct mg_context * ctx = mg_get_context(conn);
     tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data;
 
-    pthread_mutex_lock(&sMutex);
+    mg_lock_context(ctx);
     websocket_done(wsock);
     rq->conn_data = 0;
-    pthread_mutex_unlock(&sMutex);
+    mg_unlock_context(ctx);
 }
 
 
 static int runLoop = 0;
 
-static void * eventMain(void * _ignored) {
-    int i;
+static void * eventMain(void * arg) {
+
     char msg[256];
+    struct mg_context *ctx = (struct mg_context *)arg;
 
     runLoop = 1;
     while (runLoop) {
@@ -170,21 +157,15 @@ static void * eventMain(void * _ignored) {
         struct tm * timestr = localtime(&t);
         sprintf(msg,"title %s",asctime(timestr));
 
-        pthread_mutex_lock(&sMutex);
-        for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {
-            if (socketList[i] && (socketList[i]->webSockState==2)) {
-                mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, msg, strlen(msg));
-            }
-        }
-        pthread_mutex_unlock(&sMutex);
+        send_to_all_websockets(ctx, msg, strlen(msg));
 
         mg_sleep(1000);
     }
 
-    return _ignored;
+    return NULL;
 }
 
-void websock_send_broadcast(const char * data, int data_len) {
+void websock_send_broadcast(struct mg_context *ctx, const char * data, int data_len) {
 
     char buffer[260];
 
@@ -192,24 +173,20 @@ void websock_send_broadcast(const char * data, int data_len) {
         strcpy(buffer, "msg ");
         memcpy(buffer+4, data, data_len);
 
-        pthread_mutex_lock(&sMutex);
-        send_to_all_websockets(buffer, data_len+4);
-        pthread_mutex_unlock(&sMutex);
+        send_to_all_websockets(ctx, buffer, data_len+4);
     }
 }
 
-void websock_init_lib(void) {
-
-    int ret;
-    ret = pthread_mutex_init(&sMutex, 0);
-    assert(ret==0);
+void websock_init_lib(struct mg_context *ctx) {
 
+    /* todo: use variable in the ctx instead of static ones */
     memset(socketList,0,sizeof(socketList));
-
-    mg_start_thread(eventMain, 0);
+    mg_start_thread(eventMain, ctx);
 }
 
-void websock_exit_lib(void) {
+void websock_exit_lib(struct mg_context *ctx) {
 
     runLoop = 0;
+    /* todo: wait for the thread instead of a timeout */
+    mg_sleep(2000);
 }

+ 3 - 3
examples/websocket/WebSockCallbacks.h

@@ -8,10 +8,10 @@
 extern "C" {
 #endif
 
-void websock_init_lib(void);
-void websock_exit_lib(void);
+void websock_init_lib(struct mg_context *ctx);
+void websock_exit_lib(struct mg_context *ctx);
 
-void websock_send_broadcast(const char * data, int data_len);
+void websock_send_broadcast(struct mg_context *ctx, const char * data, int data_len);
 
 void websocket_ready_handler(struct mg_connection *conn);
 int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len);

+ 4 - 4
examples/websocket/websocket.c

@@ -22,12 +22,13 @@ int main(void)
         NULL
     };
 
-    websock_init_lib();
-
+    callback_funcs.init_context = websock_init_lib;
+    callback_funcs.exit_context = websock_exit_lib;
     callback_funcs.websocket_ready = websocket_ready_handler;
     callback_funcs.websocket_data = websocket_data_handler;
     callback_funcs.connection_close = connection_close_handler;
     ctx = mg_start(&callback_funcs, NULL, server_options);
+    printf("Connect to localhost:%s/websock.htm\n", mg_get_option(ctx, "listening_ports"));
 
     puts("Enter an (ASCII) character or * to exit:");
     for (;;) {
@@ -37,11 +38,10 @@ int main(void)
            break;
         }
         inbuf[0] = toupper(inbuf[0]);
-        websock_send_broadcast(inbuf, 1);
+        websock_send_broadcast(ctx, inbuf, 1);
     }
 
     mg_stop(ctx);
-    websock_exit_lib();
 
     return 0;
 }