| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 | /* This example uses deprecated interfaces: global websocket callbacks.   They have been superseeded by URI specific callbacks.   See examples/embedded_c for an up to date example.   */#include <assert.h>#include <stdlib.h>#include <time.h>#include <string.h>#include "WebSockCallbacks.h"#ifdef _WIN32#include <Windows.h>#define mg_sleep(x) Sleep(x)#else#include <unistd.h>#include <pthread.h>#define mg_sleep(x) usleep((x) * 1000)#endifstatic void send_to_all_websockets(struct mg_context *ctx, const char * data, int data_len) {    int i;    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    mg_lock_context(ctx);    for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {        if (ws_ctx->socketList[i] && (ws_ctx->socketList[i]->webSockState==2)) {            mg_websocket_write(ws_ctx->socketList[i]->conn, WEBSOCKET_OPCODE_TEXT, data, data_len);        }    }    mg_unlock_context(ctx);}void websocket_ready_handler(struct mg_connection *conn) {    int i;    const struct mg_request_info * rq = mg_get_request_info(conn);    struct mg_context * ctx = mg_get_context(conn);    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    tWebSockInfo * wsock = malloc(sizeof(tWebSockInfo));    assert(wsock);    wsock->webSockState = 0;    mg_set_user_connection_data(conn, wsock);    mg_lock_context(ctx);    for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {        if (0==ws_ctx->socketList[i]) {            ws_ctx->socketList[i] = wsock;            wsock->conn = conn;            wsock->webSockState = 1;            break;        }    }    printf("\nNew websocket attached: %s:%u\n", rq->remote_addr, rq->remote_port);    mg_unlock_context(ctx);}static void websocket_done(tWebSockContext *ws_ctx, tWebSockInfo * wsock) {    int i;    if (wsock) {        wsock->webSockState = 99;        for (i=0;i<MAX_NUM_OF_WEBSOCKS;i++) {            if (wsock==ws_ctx->socketList[i]) {                ws_ctx->socketList[i] = 0;                break;            }        }        printf("\nClose websocket attached: %s:%u\n", mg_get_request_info(wsock->conn)->remote_addr, mg_get_request_info(wsock->conn)->remote_port);        free(wsock);    }}int websocket_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len) {    const struct mg_request_info * rq = mg_get_request_info(conn);    tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data;    struct mg_context * ctx = mg_get_context(conn);    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    char msg[128];    mg_lock_context(ctx);    if (flags==136) {        // close websock        websocket_done(ws_ctx, wsock);        mg_set_user_connection_data(conn, NULL);        mg_unlock_context(ctx);        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;            }            mg_unlock_context(ctx);            return 1;        }        // chat message        if ((wsock->webSockState==2) && (!memcmp(data,"msg ",4))) {            send_to_all_websockets(ctx, data, data_len);            mg_unlock_context(ctx);            return 1;        }    }    // keep alive    if ((data_len==4) && !memcmp(data,"ping",4)) {        mg_unlock_context(ctx);        return 1;    }    mg_unlock_context(ctx);    return 0;}void connection_close_handler(const struct mg_connection *conn) {    const struct mg_request_info * rq = mg_get_request_info(conn);    tWebSockInfo * wsock = (tWebSockInfo*)rq->conn_data;    struct mg_context * ctx = mg_get_context(conn);    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    mg_lock_context(ctx);    websocket_done(ws_ctx, wsock);    mg_set_user_connection_data(conn, NULL);    mg_unlock_context(ctx);}static void * eventMain(void * arg) {    char msg[256];    struct mg_context *ctx = (struct mg_context *)arg;    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    ws_ctx->runLoop = 1;    while (ws_ctx->runLoop) {        time_t t = time(0);        struct tm * timestr = localtime(&t);        strftime(msg, sizeof(msg), "title %c", timestr);        send_to_all_websockets(ctx, msg, strlen(msg));        mg_sleep(1000);    }    return NULL;}void websock_send_broadcast(struct mg_context *ctx, const char * data, int data_len) {    char buffer[260];    if (data_len<=256) {        strcpy(buffer, "msg ");        memcpy(buffer+4, data, data_len);        send_to_all_websockets(ctx, buffer, data_len+4);    }}void websock_init_lib(const struct mg_context *ctx) {    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    memset(ws_ctx, 0, sizeof(*ws_ctx));    /* todo: use mg_start_thread_id instead of mg_start_thread */    mg_start_thread(eventMain, (void*)ctx);}void websock_exit_lib(const struct mg_context *ctx) {    tWebSockContext *ws_ctx = (tWebSockContext*) mg_get_user_data(ctx);    ws_ctx->runLoop = 0;    /* todo: wait for the thread instead of a timeout */    mg_sleep(2000);}
 |