| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 | /* 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 voidsend_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);}voidwebsocket_ready_handler(struct mg_connection *conn, void *_ignored){	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 voidwebsocket_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);	}}intwebsocket_data_handler(struct mg_connection *conn,                       int flags,                       char *data,                       size_t data_len,                       void *_ignored){	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;}voidconnection_close_handler(const struct mg_connection *conn, void *_ignored){	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;}voidwebsock_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);	}}voidwebsock_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);}voidwebsock_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);}
 |