void WebController::PrintInfo(){ mq->PrintInfo(); struct mg_connection *c = NULL; int websockets = 0; int connections = 0; // Iterate over all connections, and push current time message to websocket ones. for (c = mg_next(server, c); c != NULL; c = mg_next(server, c)) { if (c->is_websocket) { websockets++; } else { connections++; } } fprintf(stdout, "Websockets :%d\n", websockets); fprintf(stdout, "Connections :%d\n", connections); fprintf(stdout, "State :%s\n", this->interpreting ? "Interpreting" : "Stopped"); fprintf(stdout, "Config :%s\n", this->settings_file_); fprintf(stdout, "File :%s\n", this->current_gcode_file_); fprintf(stdout, "Line :%d\n", this->currentLine); fprintf(stdout, "FeedHold :%d\n", this->main_status.StopImmediateState); fprintf(stdout, "Simulating :%d\n", this->simulate); }
void RestServ::websocketBroadcast(mg_connection& nc, const char* msg, size_t len) { mg_connection* iter; for (iter = mg_next(nc.mgr, nullptr); iter != nullptr; iter = mg_next(nc.mgr, iter)) { mg_send_websocket_frame(iter, WEBSOCKET_OP_TEXT, msg, len); } }
static void push_data_to_all_websocket_connections(struct mg_mgr *m) { struct mg_connection *c; int memory_usage = (double) rand() / RAND_MAX * 100.0; for (c = mg_next(m, NULL); c != NULL; c = mg_next(m, c)) { if (c->flags & MG_F_IS_WEBSOCKET) { mg_printf_websocket_frame(c, WEBSOCKET_OP_TEXT, "%d", memory_usage); } } }
static struct mg_connection *sj_find_timer(sj_timer_id id) { struct mg_connection *c; for (c = mg_next(&sj_mgr, NULL); c != NULL; c = mg_next(&sj_mgr, c)) { if (c->handler == sj_timer_handler) { struct timer_info *ti = (struct timer_info *) c->user_data; if (ti != NULL && ti->id == id) return c; } } return NULL; }
/* * Forwards API payload to the device, by scanning through * all the connections to find those that are tagged as WebSocket. */ static void send_command_to_the_device(struct mg_mgr *mgr, const struct mg_str *cmd) { struct mg_connection *nc; for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { if (!(nc->flags & MG_F_IS_WEBSOCKET)) continue; // Ignore non-websocket requests mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, cmd->p, cmd->len); printf("Sent API command [%.*s] to %p\n", (int) cmd->len, cmd->p, nc); } }
void web_engine::push_message(const char *message) { struct mg_connection *c; if (m_server!=NULL) { // Iterate over all connections, and push current time message to websocket ones. for (c = mg_next(m_server, NULL); c != NULL; c = mg_next(m_server, c)) { if (c->is_websocket) { mg_websocket_write(c, 1, message, strlen(message)); } } } }
static void push_message(struct mg_server *server, time_t current_time) { struct mg_connection *c; char buf[20]; int len = sprintf(buf, "%lu", (unsigned long) current_time); // Iterate over all connections, and push current time message to websocket ones. for (c = mg_next(server, NULL); c != NULL; c = mg_next(server, c)) { if (c->is_websocket) { mg_websocket_write(c, 1, buf, len); } } }
int WebController::PushClientData(int opCode, const char *data , size_t data_len){ struct mg_connection *c = NULL; int nrOfClients = 0; // Iterate over all connections, and push current time message to websocket ones. for (c = mg_next(server, c); c != NULL; c = mg_next(server, c)) { if (c->is_websocket) { mg_websocket_write(c, opCode, data, data_len); nrOfClients++; } } return nrOfClients; }
static void broadcast(struct mg_connection *nc, const struct mg_str msg) { struct mg_connection *c; char buf[500]; char addr[32]; mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); snprintf(buf, sizeof(buf), "%s %.*s", addr, (int) msg.len, msg.p); printf("%s\n", buf); /* Local echo. */ for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) { if (c == nc) continue; /* Don't send to the sender. */ mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, strlen(buf)); } }
static void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr) { struct ctl_msg ctl_msg; int len = (int) MG_RECV_FUNC(mgr->ctl[1], (char *) &ctl_msg, sizeof(ctl_msg), 0); size_t dummy = MG_SEND_FUNC(mgr->ctl[1], ctl_msg.message, 1, 0); DBG(("read %d from ctl socket", len)); (void) dummy; /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 */ if (len >= (int) sizeof(ctl_msg.callback) && ctl_msg.callback != NULL) { struct mg_connection *nc; for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { ctl_msg.callback(nc, MG_EV_POLL, ctl_msg.message MG_UD_ARG(nc->user_data)); } } }
static int ws_send(lua_State *L) { struct mg_context *ctx = luaL_checkudata(L, 1, MONGOOSE_LUA); const char* key = luaL_checkstring(L, 2); size_t len; const char* data = luaL_tolstring(L, 3, &len); struct mg_connection *c = NULL; for (c = mg_next(ctx->server, NULL); c != NULL; c = mg_next(ctx->server, c)) { if (c->is_websocket && !strncmp(c->connection_param, key, 24)) { mg_websocket_printf(c, WEBSOCKET_OPCODE_TEXT, data); break; } } return MG_TRUE; }
/* --------------------------------------------------------------------------- ** V4L2 processing ** -------------------------------------------------------------------------*/ void v4l2processing(struct mg_server *server, V4l2Capture* dev, int width, int height) { if (dev->isReady()) { int fd = dev->getFd(); struct timeval tv; timerclear(&tv); fd_set read_set; FD_ZERO(&read_set); FD_SET(fd,&read_set); if (select(fd+1, &read_set, NULL, NULL, &tv) >0) { if (FD_ISSET(fd,&read_set)) { // update format informations dev->queryFormat(); // read image char buf[dev->getBufferSize()]; ssize_t size = dev->read(buf, dev->getBufferSize()); LOG(DEBUG) << "read size:" << size << " buffersize:" << dev->getBufferSize(); // compress if ( (size>0) && (dev->getFormat() == V4L2_PIX_FMT_YUYV) ) { size = yuyv2jpeg(buf, width, height, 95); } // post to subscribers if (size>0) { for (struct mg_connection *c = mg_next(server, NULL); c != NULL; c = mg_next(server, c)) { const url_handler* url = find_url(c->uri); if (url && url->handle_notify) { LOG(DEBUG) << "notify:" << c->uri << " size:" << size; url->handle_notify(c, buf, size); } } } } } } }
static void server_handler(struct mg_connection *nc, int ev, void *p) { (void) p; if (ev == MG_EV_RECV) { // Push received message to all ncections struct mbuf *io = &nc->recv_mbuf; struct mg_connection *c; for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) { if (!(c->flags |= MG_F_USER_2)) continue; // Skip non-client connections mg_send(c, io->buf, io->len); } mbuf_remove(io, io->len); } else if (ev == MG_EV_ACCEPT) { char addr[32]; mg_sock_addr_to_str(p, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); printf("New client connected from %s\n", addr); } }
/* * Forwards the jpeg frame data to all open mjpeg connections. * * Incoming messages follow a very simple binary frame format: * 4 bytes: timestamp (in network byte order) * n bytes: jpeg payload * * The timestamp is used to compute a lag. * It's done in a quite stupid way as it requires the device clock * to be synchronized with the cloud endpoint. */ static void push_frame_to_clients(struct mg_mgr *mgr, const struct websocket_message *wm) { struct mg_connection *nc; /* * mjpeg connections are tagged with the MG_F_USER_2 flag so we can find them * my scanning the connection list provided by the mongoose manager. */ for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { if (!(nc->flags & MG_F_USER_2)) continue; // Ignore un-marked requests mg_printf(nc, "--w00t\r\nContent-Type: image/jpeg\r\n" "Content-Length: %lu\r\n\r\n", (unsigned long) wm->size); mg_send(nc, wm->data, wm->size); mg_send(nc, "\r\n", 2); printf("Image pushed to %p\n", nc); } }
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) { struct mg_connection *nc; double now; double min_timer = 0; int num_timers = 0; mg_ev_mgr_lwip_process_signals(mgr); for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; if (nc->ev_timer_time > 0) { if (num_timers == 0 || nc->ev_timer_time < min_timer) { min_timer = nc->ev_timer_time; } num_timers++; } if (nc->send_mbuf.len > 0 #if MG_ENABLE_SSL || (nc->flags & MG_F_WANT_WRITE) #endif ) { int can_send = 0; /* We have stuff to send, but can we? */ if (nc->flags & MG_F_UDP) { /* UDP is always ready for sending. */ can_send = (cs->pcb.udp != NULL); } else { can_send = (cs->pcb.tcp != NULL && cs->pcb.tcp->snd_buf > 0); } /* We want and can send, request a poll immediately. */ if (can_send) return 0; } } uint32_t timeout_ms = ~0; now = mg_time(); if (num_timers > 0) { /* If we have a timer that is past due, do a poll ASAP. */ if (min_timer < now) return 0; double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */; if (timer_timeout_ms < timeout_ms) { timeout_ms = timer_timeout_ms; } } return timeout_ms; }
static void handle_websocket_message(struct mg_connection *conn) { struct conn_data *d = (struct conn_data *) conn->connection_param; struct mg_connection *c; printf("[%.*s]\n", (int) conn->content_len, conn->content); if (conn->content_len > 5 && !memcmp(conn->content, "join ", 5)) { // Client joined new room d->room = conn->content[5]; } else if (conn->content_len > 4 && !memcmp(conn->content, "msg ", 4) && d->room != 0 && d->room != '?') { // Client has sent a message. Push this message to all clients // that are subscribed to the same room as client for (c = mg_next(s_server, NULL); c != NULL; c = mg_next(s_server, c)) { struct conn_data *d2 = (struct conn_data *) c->connection_param; if (!c->is_websocket || d2->room != d->room) continue; mg_websocket_printf(c, WEBSOCKET_OPCODE_TEXT, "msg %c %p %.*s", (char) d->room, conn, conn->content_len - 4, conn->content + 4); } } }
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) { struct mg_connection *nc; double now = mg_time(); double min_timer = 0; int num_timers = 0; mg_ev_mgr_lwip_process_signals(mgr); for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) { if (nc->ev_timer_time > 0) { if (num_timers == 0 || nc->ev_timer_time < min_timer) { min_timer = nc->ev_timer_time; } num_timers++; } } uint32_t timeout_ms = ~0; if (num_timers > 0) { double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */; if (timer_timeout_ms < timeout_ms) { timeout_ms = timer_timeout_ms; } } return timeout_ms; }
void mpd_poll(struct mg_server *s) { switch (mpd.conn_state) { case MPD_DISCONNECTED: /* Try to connect */ fprintf(stdout, "MPD Connecting to %s:%d\n", mpd.host, mpd.port); mpd.conn = mpd_connection_new(mpd.host, mpd.port, 3000); if (mpd.conn == NULL) { fprintf(stderr, "Out of memory."); mpd.conn_state = MPD_FAILURE; return; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) { fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn)); for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) { c->callback_param = (void *)mpd_connection_get_error_message(mpd.conn); mpd_notify_callback(c, MG_POLL); } mpd.conn_state = MPD_FAILURE; return; } if(mpd.password && !mpd_run_password(mpd.conn, mpd.password)) { fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn)); for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) { c->callback_param = (void *)mpd_connection_get_error_message(mpd.conn); mpd_notify_callback(c, MG_POLL); } mpd.conn_state = MPD_FAILURE; return; } fprintf(stderr, "MPD connected.\n"); mpd_connection_set_timeout(mpd.conn, 10000); mpd.conn_state = MPD_CONNECTED; /* write outputs */ mpd.buf_size = mpd_put_outputs(mpd.buf, 1); for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) { c->callback_param = NULL; mpd_notify_callback(c, MG_POLL); } break; case MPD_FAILURE: fprintf(stderr, "MPD connection failed.\n"); case MPD_DISCONNECT: case MPD_RECONNECT: if(mpd.conn != NULL) mpd_connection_free(mpd.conn); mpd.conn = NULL; mpd.conn_state = MPD_DISCONNECTED; break; case MPD_CONNECTED: mpd.buf_size = mpd_put_state(mpd.buf, &mpd.song_id, &mpd.queue_version); for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) { c->callback_param = NULL; mpd_notify_callback(c, MG_POLL); } mpd.buf_size = mpd_put_outputs(mpd.buf, 0); for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) { c->callback_param = NULL; mpd_notify_callback(c, MG_POLL); } break; } }
void http_ws_push_json(struct mg_server *server, JsonNode *obj) { struct mg_connection *c; JsonNode *j; int len; char *js, *u = NULL, *d = NULL; if (!obj || obj->tag != JSON_OBJECT) return; /* * Iterate over connections and push message to the WS connections. */ for (c = mg_next(server, NULL); c != NULL; c = mg_next(server, c)) { if (c->is_websocket) { #if 0 { int n; for (n = 0; n < c->num_headers; n++) { struct mg_header *hh; hh = &c->http_headers[n]; if (*hh->name == 'X') { fprintf(stderr, "WEBSOCKET-HEADER: %s=%s\n", hh->name, hh->value); } } } puts(json_stringify(obj, NULL)); #endif u = field(c, "user"); d = field(c, "device"); if (u) { if ((j = json_find_member(obj, "user")) != NULL) { if (strcasecmp(u, j->string_) != 0) { fprintf(stderr, "not for %s; skip\n", u); free(u); continue; } } if (d) { if ((j = json_find_member(obj, "device")) != NULL) { if (strcasecmp(d, j->string_) != 0) { fprintf(stderr, "not for %s/%s; skip\n", u, d); free(u); free(d); continue; } } } free(u); if (d) free(d); } if ((js = json_stringify(obj, NULL)) != NULL) { len = strlen(js); mg_websocket_write(c, 1, js, len); free(js); } } } }