mirror of
https://github.com/nasa/trick.git
synced 2024-12-24 07:16:41 +00:00
Add Websocket sessions to experimental mongoose-based embedded web server. Ref #828
This commit is contained in:
parent
053bcfe0b2
commit
e6b6312396
@ -3,27 +3,38 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>WS Experiments</title>
|
<title>WS Experiments</title>
|
||||||
</head>
|
</head>
|
||||||
<style>
|
|
||||||
table { border-collapse: collapse; width: 100%; }
|
|
||||||
th, td { text-align: left; padding: 8px; }
|
|
||||||
tr:nth-child(even){background-color: #f2f2f2}
|
|
||||||
th { background-color: #562399; color: white; }
|
|
||||||
</style>
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
</header>
|
</header>
|
||||||
<section>
|
<section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<div id="output"></div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function sendMessage(msg) {
|
||||||
|
ws.send(msg);
|
||||||
|
log("Message sent");
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(s) {
|
||||||
|
var p = document.createElement("p");
|
||||||
|
p.style.wordWrap = "break-word";
|
||||||
|
p.textContent = s;
|
||||||
|
output.appendChild(p);
|
||||||
|
//console.log(s);
|
||||||
|
}
|
||||||
|
|
||||||
var ws = new WebSocket("ws://localhost:8888", "myProtocol");
|
var ws = new WebSocket("ws://localhost:8888", "myProtocol");
|
||||||
|
|
||||||
// Event handler for the WebSocket connection opening
|
// Event handler for the WebSocket connection opening
|
||||||
ws.onopen = function(e) {
|
ws.onopen = function(e) {
|
||||||
console.log("Connection established");
|
log("Connection established");
|
||||||
|
sendMessage("Hello WebSocket Server from Browser Client!");
|
||||||
};
|
};
|
||||||
// Event handler for receiving text messages
|
// Event handler for receiving text messages
|
||||||
ws.onmessage = function(e) {
|
ws.onmessage = function(e) {
|
||||||
console.log("Message received", e, e.data);
|
log(e.data);
|
||||||
};
|
};
|
||||||
// Event handler for errors in the WebSocket object
|
// Event handler for errors in the WebSocket object
|
||||||
ws.onerror = function(e) {
|
ws.onerror = function(e) {
|
||||||
|
BIN
trick_sims/Cannon/SIM_cannon_numeric/www/images/trick_icon.png
Normal file
BIN
trick_sims/Cannon/SIM_cannon_numeric/www/images/trick_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@ -1,13 +1,18 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
|
||||||
<title>Trick Simulation Pages</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div style="background:#efefff">
|
<head>
|
||||||
<h2>SIM_cannon_numeric</h2>
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
</div>
|
<title>Trick Simulation</title>
|
||||||
|
<div class="header">
|
||||||
|
<table>
|
||||||
|
<th><img src="images/trick_icon.png" height="64" width="64"></th>
|
||||||
|
<th><h1>SIM_cannon_numeric</h1></th>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
<div style="background:#efefef">
|
<div style="background:#efefef">
|
||||||
<ul>
|
<ul>
|
||||||
@ -21,6 +26,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href="/apps/vs_connections.html">Variable Server Connections</a></li>
|
<li><a href="/apps/vs_connections.html">Variable Server Connections</a></li>
|
||||||
<li><a href="/apps/alloc_info.html">Trick Memory Allocations</a></li>
|
<li><a href="/apps/alloc_info.html">Trick Memory Allocations</a></li>
|
||||||
|
<li><a href="/apps/wsexp.html">Websocket Experiment</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
19
trick_sims/Cannon/SIM_cannon_numeric/www/style.css
Normal file
19
trick_sims/Cannon/SIM_cannon_numeric/www/style.css
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
h1 {
|
||||||
|
font-family: fantasy, cursive, serif;
|
||||||
|
font-size: 32px;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.header { background-image: linear-gradient(#afafff, white); }
|
||||||
|
|
36
trick_sims/Cannon/models/mongoose_httpd/include/WSSession.hh
Normal file
36
trick_sims/Cannon/models/mongoose_httpd/include/WSSession.hh
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*************************************************************************
|
||||||
|
PURPOSE: (Represent Websocket variable server connection.)
|
||||||
|
LIBRARY DEPENDENCIES:
|
||||||
|
( (../src/WSSession.cpp))
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef WSSESSION_HH
|
||||||
|
#define WSSESSION_HH
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <mongoose.h>
|
||||||
|
|
||||||
|
inline uint64_t to_nanoseconds(struct timespec* t) {
|
||||||
|
return t->tv_sec * (uint64_t)1000000000L + t->tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
class WSsession {
|
||||||
|
|
||||||
|
public:
|
||||||
|
WSsession( struct mg_connection *c );
|
||||||
|
void setTimeInterval(unsigned int milliseconds);
|
||||||
|
void addVariable(const char* vname);
|
||||||
|
void sendValues();
|
||||||
|
void synchSend(); // This must be called at a frequency greater than or equal to the interval.
|
||||||
|
void pause();
|
||||||
|
void unpause();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WSsession() {}
|
||||||
|
struct mg_connection* connection;
|
||||||
|
std::vector<const char*> varNames;
|
||||||
|
struct timespec lastTime;
|
||||||
|
struct timespec interval;
|
||||||
|
bool enabled;
|
||||||
|
};
|
||||||
|
#endif
|
57
trick_sims/Cannon/models/mongoose_httpd/src/WSSession.cpp
Normal file
57
trick_sims/Cannon/models/mongoose_httpd/src/WSSession.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "../include/WSSession.hh"
|
||||||
|
|
||||||
|
WSsession::WSsession( struct mg_connection *c ) {
|
||||||
|
connection = c;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &lastTime);
|
||||||
|
setTimeInterval(1000); // Default time interval is one second.
|
||||||
|
}
|
||||||
|
void WSsession::setTimeInterval(unsigned int milliseconds) {
|
||||||
|
interval.tv_sec = milliseconds / 1000;
|
||||||
|
interval.tv_nsec = (milliseconds % 1000) * 1000000L;
|
||||||
|
}
|
||||||
|
void WSsession::addVariable(const char* vname){
|
||||||
|
varNames.push_back(vname);
|
||||||
|
}
|
||||||
|
void WSsession::sendValues() {
|
||||||
|
std::vector<const char*>::iterator it;
|
||||||
|
for (it = varNames.begin(); it != varNames.end(); it++ ) {
|
||||||
|
// ==================================================================
|
||||||
|
// FIXME: Get the values of the variables and send them to the client.
|
||||||
|
// Currently we just send the names for testing.
|
||||||
|
// ==================================================================
|
||||||
|
mg_send_websocket_frame(connection, WEBSOCKET_OP_TEXT, *it, strlen(*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void WSsession::synchSend() { // This must be called at a frequency greater than or equal to the interval.
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
|
||||||
|
if (to_nanoseconds(&now) - to_nanoseconds(&lastTime) >= to_nanoseconds(&interval)) {
|
||||||
|
if (enabled) {
|
||||||
|
sendValues();
|
||||||
|
}
|
||||||
|
lastTime = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void WSsession::pause() { enabled = false;}
|
||||||
|
void WSsession::unpause() { enabled = true; }
|
||||||
|
|
||||||
|
// int main ( int argc, char* argv[]) {
|
||||||
|
// WSsessionMap wsmap;
|
||||||
|
// struct mg_connection *c
|
||||||
|
// WSsession* wsess = new WSsession(c);
|
||||||
|
// struct timespec nap, t2;
|
||||||
|
|
||||||
|
// nap.tv_sec = 0;
|
||||||
|
// nap.tv_nsec = 10000000L;
|
||||||
|
//
|
||||||
|
// wsess->setTimeInterval(500);
|
||||||
|
// wsess->addVariable("dyn.cannon.pos[0]");
|
||||||
|
// wsess->addVariable("dyn.cannon.pos[1]");
|
||||||
|
// wsess->unpause();
|
||||||
|
//
|
||||||
|
// while(1) {
|
||||||
|
// wsess->synchSend();
|
||||||
|
// if ( nanosleep(&nap, &t2) < 0) { return -1; };
|
||||||
|
// }
|
||||||
|
// return 0;
|
||||||
|
// }
|
@ -1,8 +1,45 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
PURPOSE: (Represent the state and initial conditions of an http server)
|
PURPOSE: (Represent the state and initial conditions of an http server)
|
||||||
|
LIBRARY DEPENDENCIES:
|
||||||
|
((WSSession.o))
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
/*
|
||||||
|
Messages sent from Client to Server
|
||||||
|
================================
|
||||||
|
{ "cmd" : "var_add",
|
||||||
|
"var_name" : <str>
|
||||||
|
}
|
||||||
|
{ "cmd" : "var_pause" }
|
||||||
|
{ "cmd" : "var_unpause" }
|
||||||
|
{ "cmd" : "var_send" }
|
||||||
|
{ "cmd" : "var_clear" }
|
||||||
|
{ "cmd" : "var_exit" }
|
||||||
|
{ "cmd" : "var_cycle",
|
||||||
|
"period" : <int>
|
||||||
|
}
|
||||||
|
|
||||||
|
Messages sent from Server to Client
|
||||||
|
=================================
|
||||||
|
{ "msg_type" : "error",
|
||||||
|
"error_text" : <str>
|
||||||
|
}
|
||||||
|
{ "msg_type" : "var_list"
|
||||||
|
"values" : []
|
||||||
|
}
|
||||||
|
|
||||||
|
LEXEMES:
|
||||||
|
{
|
||||||
|
}
|
||||||
|
"[^""]"
|
||||||
|
:
|
||||||
|
,
|
||||||
|
[0-9]+
|
||||||
|
}
|
||||||
|
*/
|
||||||
#include "../include/http_server.h"
|
#include "../include/http_server.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "../include/WSSession.hh"
|
||||||
|
|
||||||
#include "trick/VariableServer.hh"
|
#include "trick/VariableServer.hh"
|
||||||
extern Trick::VariableServer * the_vs ;
|
extern Trick::VariableServer * the_vs ;
|
||||||
@ -13,6 +50,14 @@ static const struct mg_str s_get_method = MG_MK_STR("GET");
|
|||||||
static const struct mg_str s_put_method = MG_MK_STR("PUT");
|
static const struct mg_str s_put_method = MG_MK_STR("PUT");
|
||||||
static const struct mg_str s_delele_method = MG_MK_STR("DELETE");
|
static const struct mg_str s_delele_method = MG_MK_STR("DELETE");
|
||||||
|
|
||||||
|
static int is_equal(const struct mg_str *s1, const struct mg_str *s2) {
|
||||||
|
return s1->len == s2->len && memcmp(s1->p, s2->p, s2->len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int has_prefix(const struct mg_str *uri, const struct mg_str *prefix) {
|
||||||
|
return uri->len > prefix->len && memcmp(uri->p, prefix->p, prefix->len) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
int getIntegerQueryValue(struct http_message *hm, const char* key, int defaultVal) {
|
int getIntegerQueryValue(struct http_message *hm, const char* key, int defaultVal) {
|
||||||
char value_text[100];
|
char value_text[100];
|
||||||
if ( mg_get_http_var(&(hm->query_string), key, value_text, sizeof(value_text)) > 0) {
|
if ( mg_get_http_var(&(hm->query_string), key, value_text, sizeof(value_text)) > 0) {
|
||||||
@ -22,8 +67,10 @@ int getIntegerQueryValue(struct http_message *hm, const char* key, int defaultVa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_vs_connections_call(struct mg_connection *nc, struct http_message *hm) {
|
static const struct mg_str api_prefix = MG_MK_STR("/api/v1");
|
||||||
/* Send headers */
|
|
||||||
|
// Respond to HTTP GET with URI="/api/v1/vs_connections".
|
||||||
|
void handle_HTTP_GET_vs_connections(struct mg_connection *nc, struct http_message *hm) {
|
||||||
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << *the_vs << std::endl;
|
ss << *the_vs << std::endl;
|
||||||
@ -32,7 +79,8 @@ void handle_vs_connections_call(struct mg_connection *nc, struct http_message *h
|
|||||||
mg_send_http_chunk(nc, "", 0);
|
mg_send_http_chunk(nc, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_alloc_info_call(struct mg_connection *nc, struct http_message *hm) {
|
// Respond to HTTP GET with URI="/api/v1/alloc_info".
|
||||||
|
void handle_HTTP_GET_alloc_info(struct mg_connection *nc, struct http_message *hm) {
|
||||||
int start = getIntegerQueryValue(hm, "start", 0);
|
int start = getIntegerQueryValue(hm, "start", 0);
|
||||||
int count = getIntegerQueryValue(hm, "count", 10);
|
int count = getIntegerQueryValue(hm, "count", 10);
|
||||||
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
|
||||||
@ -43,16 +91,10 @@ void handle_alloc_info_call(struct mg_connection *nc, struct http_message *hm) {
|
|||||||
mg_send_http_chunk(nc, "", 0);
|
mg_send_http_chunk(nc, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int has_prefix(const struct mg_str *uri, const struct mg_str *prefix) {
|
// =============================================================================
|
||||||
return uri->len > prefix->len && memcmp(uri->p, prefix->p, prefix->len) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_equal(const struct mg_str *s1, const struct mg_str *s2) {
|
|
||||||
return s1->len == s2->len && memcmp(s1->p, s2->p, s2->len) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mg_serve_http_opts http_server_options;
|
static struct mg_serve_http_opts http_server_options;
|
||||||
static const struct mg_str api_prefix = MG_MK_STR("/api/v1");
|
std::map<mg_connection*, WSsession*> wsSessionMap;
|
||||||
|
|
||||||
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
||||||
|
|
||||||
@ -60,32 +102,70 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
|
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
|
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
|
||||||
printf("DEBUG: Event MG_EV_WEBSOCKET_HANDSHAKE_DONE.\n");
|
#ifdef DEBUG
|
||||||
const char* s = "Bingo boingo.";
|
printf("DEBUG: Event MG_EV_WEBSOCKET_HANDSHAKE_DONE. nc = %p.\n", nc);
|
||||||
mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, s, strlen(s));
|
#endif
|
||||||
|
WSsession* session = new WSsession(nc);
|
||||||
|
|
||||||
|
session->setTimeInterval(500); // TEMPORARY for development
|
||||||
|
session->addVariable("dyn.cannon.pos[0]");// TEMPORARY for development
|
||||||
|
session->addVariable("dyn.cannon.pos[1]");// TEMPORARY for development
|
||||||
|
session->unpause(); // TEMPORARY for development
|
||||||
|
|
||||||
|
wsSessionMap.insert( std::pair<mg_connection*, WSsession*>(nc, session) );
|
||||||
} break;
|
} break;
|
||||||
case MG_EV_WEBSOCKET_FRAME: {
|
case MG_EV_WEBSOCKET_FRAME: {
|
||||||
printf("DEBUG: Event MG_EV_WEBSOCKET_FRAME.\n");
|
// Process messages recieved from the (web browser) client.
|
||||||
|
struct websocket_message *wm = (struct websocket_message *) ev_data;
|
||||||
|
|
||||||
|
char* msg = strndup((char*)wm->data, wm->size);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("DEBUG: Even t MG_EV_WEBSOCKET_FRAME: nc = %p message = %s\n", nc, msg);
|
||||||
|
#endif
|
||||||
|
free(msg);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case MG_EV_CONNECT: {
|
case MG_EV_CONNECT: {
|
||||||
printf("DEBUG: Event MG_EV_CONNECT.\n");
|
#ifdef DEBUG
|
||||||
|
printf("DEBUG: Event MG_EV_CONNECT. nc = %p.\n", nc);
|
||||||
|
#endif
|
||||||
} break;
|
} break;
|
||||||
// case MG_EV_RECV: {
|
|
||||||
// printf("DEBUG: Event MG_EV_RECV.\n");
|
|
||||||
// } break;
|
|
||||||
// case MG_EV_SEND: {
|
|
||||||
// printf("DEBUG: Event MG_EV_SEND.\n");
|
|
||||||
// } break;
|
|
||||||
case MG_EV_CLOSE: {
|
case MG_EV_CLOSE: {
|
||||||
printf("DEBUG: Event MG_EV_CLOSE.\n");
|
#ifdef DEBUG
|
||||||
|
printf("DEBUG: Event MG_EV_CLOSE. nc = %p.\n", nc);
|
||||||
|
#endif
|
||||||
|
if (nc->flags & MG_F_IS_WEBSOCKET) {
|
||||||
|
std::map<mg_connection*, WSsession*>::iterator iter;
|
||||||
|
iter = wsSessionMap.find(nc);
|
||||||
|
if (iter != wsSessionMap.end()) {
|
||||||
|
WSsession* session = iter->second;
|
||||||
|
delete session;
|
||||||
|
wsSessionMap.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case MG_EV_POLL: {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("DEBUG: Event MG_EV_POLL. nc = %p.\n", nc);
|
||||||
|
#endif
|
||||||
|
if (nc->flags & MG_F_IS_WEBSOCKET) {
|
||||||
|
std::map<mg_connection*, WSsession*>::iterator iter;
|
||||||
|
// Find the session that goes with this connection.
|
||||||
|
iter = wsSessionMap.find(nc);
|
||||||
|
if (iter != wsSessionMap.end()) {
|
||||||
|
WSsession* session = iter->second;
|
||||||
|
session->synchSend();
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
// case MG_EV_POLL: {
|
|
||||||
// printf("DEBUG: Event MG_EV_POLL.\n");
|
|
||||||
// } break;
|
|
||||||
case MG_EV_HTTP_REQUEST: {
|
case MG_EV_HTTP_REQUEST: {
|
||||||
|
#ifdef DEBUG
|
||||||
printf("DEBUG: Event MG_EV_HTTP_REQUEST.\n");
|
printf("DEBUG: Event MG_EV_HTTP_REQUEST.\n");
|
||||||
|
#endif
|
||||||
char * s = strndup(hm->uri.p, hm->uri.len);
|
char * s = strndup(hm->uri.p, hm->uri.len);
|
||||||
|
#ifdef DEBUG
|
||||||
printf("DEBUG: URI = \"%s\"\n", s);
|
printf("DEBUG: URI = \"%s\"\n", s);
|
||||||
|
#endif
|
||||||
free(s);
|
free(s);
|
||||||
if (has_prefix(&hm->uri, &api_prefix)) {
|
if (has_prefix(&hm->uri, &api_prefix)) {
|
||||||
struct mg_str key;
|
struct mg_str key;
|
||||||
@ -93,16 +173,22 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
key.len = hm->uri.len - api_prefix.len;
|
key.len = hm->uri.len - api_prefix.len;
|
||||||
|
|
||||||
if (is_equal(&hm->method, &s_get_method)) {
|
if (is_equal(&hm->method, &s_get_method)) {
|
||||||
|
#ifdef DEBUG
|
||||||
printf("DEBUG: HTTP GET method.\n");
|
printf("DEBUG: HTTP GET method.\n");
|
||||||
|
#endif
|
||||||
if (mg_vcmp(&key, "/vs_connections") == 0) {
|
if (mg_vcmp(&key, "/vs_connections") == 0) {
|
||||||
handle_vs_connections_call(nc, hm);
|
handle_HTTP_GET_vs_connections(nc, hm);
|
||||||
} else if (mg_vcmp(&key, "/alloc_info") == 0) {
|
} else if (mg_vcmp(&key, "/alloc_info") == 0) {
|
||||||
handle_alloc_info_call(nc, hm);
|
handle_HTTP_GET_alloc_info(nc, hm);
|
||||||
}
|
}
|
||||||
} else if (is_equal(&hm->method, &s_put_method)) {
|
} else if (is_equal(&hm->method, &s_put_method)) {
|
||||||
|
#ifdef DEBUG
|
||||||
printf("DEBUG: HTTP PUT method.\n");
|
printf("DEBUG: HTTP PUT method.\n");
|
||||||
|
#endif
|
||||||
} else if (is_equal(&hm->method, &s_delele_method)) {
|
} else if (is_equal(&hm->method, &s_delele_method)) {
|
||||||
|
#ifdef DEBUG
|
||||||
printf("DEBUG: HTTP DELETE method.\n");
|
printf("DEBUG: HTTP DELETE method.\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mg_serve_http(nc, (struct http_message *) ev_data, http_server_options);
|
mg_serve_http(nc, (struct http_message *) ev_data, http_server_options);
|
||||||
@ -115,8 +201,14 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
|
|||||||
|
|
||||||
void* service_connections (void* arg) {
|
void* service_connections (void* arg) {
|
||||||
HTTP_Server *S = (HTTP_Server*)arg;
|
HTTP_Server *S = (HTTP_Server*)arg;
|
||||||
while(!S->shutting_down) {
|
while (!S->shutting_down) {
|
||||||
mg_mgr_poll(&S->mgr, 1000);
|
mg_mgr_poll(&S->mgr, 1000);
|
||||||
|
struct timespec nap, t2;
|
||||||
|
nap.tv_sec = 0;
|
||||||
|
nap.tv_nsec = 100000000L;
|
||||||
|
if ( nanosleep(&nap, &t2) < 0) {
|
||||||
|
// Error
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user