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;
+}