diff --git a/VS2012/ex_websocket/ex_websocket.vcxproj b/VS2012/ex_websocket/ex_websocket.vcxproj index e56d3859..c1bdc32f 100644 --- a/VS2012/ex_websocket/ex_websocket.vcxproj +++ b/VS2012/ex_websocket/ex_websocket.vcxproj @@ -27,7 +27,6 @@ Application true - v110_xp Unicode @@ -39,7 +38,6 @@ Application false - v110_xp true Unicode @@ -150,6 +148,7 @@ + diff --git a/examples/websocket/WebSockCallbacks.c b/examples/websocket/WebSockCallbacks.c index ef37ce24..d90f712a 100644 --- a/examples/websocket/WebSockCallbacks.c +++ b/examples/websocket/WebSockCallbacks.c @@ -7,21 +7,21 @@ #include 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; + 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; + return CloseHandle(*mutex) == 0 ? -1 : 0; } static int pthread_mutex_lock(pthread_mutex_t *mutex) { - return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0? 0 : -1; + return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0? 0 : -1; } static int pthread_mutex_unlock(pthread_mutex_t *mutex) { - return ReleaseMutex(*mutex) == 0 ? -1 : 0; + return ReleaseMutex(*mutex) == 0 ? -1 : 0; } #define mg_sleep(x) Sleep(x) #else @@ -32,9 +32,9 @@ static int pthread_mutex_unlock(pthread_mutex_t *mutex) { typedef struct tWebSockInfo { - int webSockState; - unsigned long initId; - struct mg_connection *conn; + int webSockState; + unsigned long initId; + struct mg_connection *conn; } tWebSockInfo; static pthread_mutex_t sMutex; @@ -43,138 +43,167 @@ static pthread_mutex_t sMutex; static tWebSockInfo *socketList[MAX_NUM_OF_WEBSOCKS]; -void websocket_ready_handler(struct mg_connection *conn) { +static void send_to_all_websockets(const char * data, int data_len) { - int i; - struct mg_request_info * rq = mg_get_request_info(conn); - tWebSockInfo * wsock = malloc(sizeof(tWebSockInfo)); - assert(wsock); - wsock->webSockState = 0; - rq->conn_data = wsock; + int i; - pthread_mutex_lock(&sMutex); - for (i=0;iconn = conn; - wsock->webSockState = 1; - break; + for (i=0;iwebSockState==2)) { + mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, data, data_len); + } } - } - pthread_mutex_unlock(&sMutex); } -static void websocket_done(tWebSockInfo * wsock) { - int i; - if (wsock) { - wsock->webSockState = 99; +void websocket_ready_handler(struct mg_connection *conn) { + + int i; + struct mg_request_info * rq = mg_get_request_info(conn); + tWebSockInfo * wsock = malloc(sizeof(tWebSockInfo)); + assert(wsock); + wsock->webSockState = 0; + rq->conn_data = wsock; + + pthread_mutex_lock(&sMutex); for (i=0;iconn = conn; + wsock->webSockState = 1; + break; + } + } + pthread_mutex_unlock(&sMutex); +} + + +static void websocket_done(tWebSockInfo * wsock) { + int i; + if (wsock) { + wsock->webSockState = 99; + for (i=0;iconn_data; - char msg[128]; - int i; + struct mg_request_info * rq = mg_get_request_info(conn); + tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data; + char msg[128]; - pthread_mutex_lock(&sMutex); - if (flags==136) { - // close websock + pthread_mutex_lock(&sMutex); + if (flags==136) { + // close websock + websocket_done(wsock); + rq->conn_data = 0; + pthread_mutex_unlock(&sMutex); + return 1; + } + if ((data_len>=5) && (data_len<100) && (flags==129) || (flags==130)) { + + // init command + if ((wsock->webSockState==1) && (!memcmp(data,"init ",5))) { + char * chk; + unsigned long gid; + memcpy(msg,data+5,data_len-5); + msg[data_len-5]=0; + gid = strtoul(msg,&chk,10); + wsock->initId = gid; + if (gid>0 && chk!=NULL && *chk==0) { + wsock->webSockState = 2; + } + pthread_mutex_unlock(&sMutex); + return 1; + } + + // chat message + if ((wsock->webSockState==2) && (!memcmp(data,"msg ",4))) { + send_to_all_websockets(data, data_len); + pthread_mutex_unlock(&sMutex); + return 1; + } + } + + // keep alive + if ((data_len==4) && !memcmp(data,"ping",4)) { + pthread_mutex_unlock(&sMutex); + return 1; + } + + pthread_mutex_unlock(&sMutex); + return 0; +} + + +void connection_close_handler(struct mg_connection *conn) { + struct mg_request_info * rq = mg_get_request_info(conn); + tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data; + + pthread_mutex_lock(&sMutex); websocket_done(wsock); rq->conn_data = 0; pthread_mutex_unlock(&sMutex); - return 1; - } - if ((data_len>=5) && (data_len<100) && (flags==129) || (flags==130)) { - - // init command - if ((wsock->webSockState==1) && (!memcmp(data,"init ",5))) { - char * chk; - unsigned long gid; - memcpy(msg,data+5,data_len-5); - msg[data_len-5]=0; - gid = strtoul(msg,&chk,10); - wsock->initId = gid; - if (gid>0 && chk!=NULL && *chk==0) { - wsock->webSockState = 2; - } - pthread_mutex_unlock(&sMutex); - return 1; - } - - // chat message - if ((wsock->webSockState==2) && (!memcmp(data,"msg ",4))) { - for (i=0;iwebSockState==2)) { - mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, data, data_len); - } - } - pthread_mutex_unlock(&sMutex); - return 1; - } - } - - // keep alive - if ((data_len==4) && !memcmp(data,"ping",4)) { - pthread_mutex_unlock(&sMutex); - return 1; - } - - pthread_mutex_unlock(&sMutex); - return 0; } -void connection_close_handler(struct mg_connection *conn) { - struct mg_request_info * rq = mg_get_request_info(conn); - tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data; - - pthread_mutex_lock(&sMutex); - websocket_done(wsock); - rq->conn_data = 0; - pthread_mutex_unlock(&sMutex); -} - +static int runLoop = 0; static void * eventMain(void * _ignored) { - int i; - char msg[256]; - for (;;) { - time_t t = time(0); - struct tm * timestr = localtime(&t); - sprintf(msg,"title %s",asctime(timestr)); + int i; + char msg[256]; - pthread_mutex_lock(&sMutex); - for (i=0;iwebSockState==2)) { - mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, msg, strlen(msg)); - } + runLoop = 1; + while (runLoop) { + time_t t = time(0); + struct tm * timestr = localtime(&t); + sprintf(msg,"title %s",asctime(timestr)); + + pthread_mutex_lock(&sMutex); + for (i=0;iwebSockState==2)) { + mg_websocket_write(socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, msg, strlen(msg)); + } + } + pthread_mutex_unlock(&sMutex); + + mg_sleep(1000); } - pthread_mutex_unlock(&sMutex); - mg_sleep(1000); - } - - return _ignored; + return _ignored; } +void websock_send_broadcast(const char * data, int data_len) { + + char buffer[260]; + + if (data_len<=256) { + 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); + } +} void websock_init_lib(void) { - int ret; - ret = pthread_mutex_init(&sMutex, 0); - assert(ret==0); - memset(socketList,0,sizeof(socketList)); + int ret; + ret = pthread_mutex_init(&sMutex, 0); + assert(ret==0); - mg_start_thread(eventMain, 0); + memset(socketList,0,sizeof(socketList)); + + mg_start_thread(eventMain, 0); } +void websock_exit_lib(void) { + + runLoop = 0; +} diff --git a/examples/websocket/WebSockCallbacks.h b/examples/websocket/WebSockCallbacks.h index 2bd8f1e0..4122a216 100644 --- a/examples/websocket/WebSockCallbacks.h +++ b/examples/websocket/WebSockCallbacks.h @@ -9,6 +9,10 @@ extern "C" { #endif void websock_init_lib(void); +void websock_exit_lib(void); + +void websock_send_broadcast(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); void connection_close_handler(struct mg_connection *conn); diff --git a/examples/websocket/websocket.c b/examples/websocket/websocket.c new file mode 100644 index 00000000..06349569 --- /dev/null +++ b/examples/websocket/websocket.c @@ -0,0 +1,47 @@ +#include +#include +#include + +#include "civetweb.h" +#include "WebSockCallbacks.h" + +int main(void) +{ + struct mg_context *ctx = 0; + struct mg_callbacks callback_funcs = {0}; + char inbuf[4]; + + const char *server_options[] = { + /* document_root: The path to the test function websock.htm */ + "document_root", "../../examples/websocket", + + /* port: use http standard to match websocket url in websock.htm: ws://127.0.0.1/MyWebSock */ + /* if the port is changed here, it needs to be changed in websock.htm as wenn */ + "listening_ports", "80", + + NULL + }; + + websock_init_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); + + puts("Enter an (ASCII) character or * to exit:"); + for (;;) { + fgets(inbuf, sizeof(inbuf), stdin); + + if (inbuf[0]=='*') { + break; + } + inbuf[0] = toupper(inbuf[0]); + websock_send_broadcast(inbuf, 1); + } + + mg_stop(ctx); + websock_exit_lib(); + + return 0; +}