Add the ability to add new types of WebSocketSessions to make server extensible

This commit is contained in:
Penn, John M 047828115 2019-08-20 18:14:47 -05:00
parent 2998180231
commit 2e08379e42
10 changed files with 154 additions and 126 deletions

View File

@ -107,7 +107,7 @@ function updatePage(start, count) {
updateHeader(allocData); updateHeader(allocData);
} }
} }
xhr.open('GET', `/api/v1/alloc_info?start=${start}&count=${count}`); xhr.open('GET', `/api/http/alloc_info?start=${start}&count=${count}`);
xhr.send(null); xhr.send(null);
} }
@ -148,7 +148,7 @@ xhr.onreadystatechange = function() {
updateHeader(allocData); updateHeader(allocData);
} }
} }
xhr.open('GET', '/api/v1/alloc_info?start=0&count=10'); xhr.open('GET', '/api/http/alloc_info?start=0&count=10');
xhr.send(null); xhr.send(null);
</script> </script>

View File

@ -67,7 +67,7 @@
showVSConnections(myObj); showVSConnections(myObj);
} }
} }
xhr.open('GET', '/api/v1/vs_connections'); xhr.open('GET', '/api/http/vs_connections');
xhr.send(null); xhr.send(null);
</script> </script>
</body> </body>

View File

@ -57,7 +57,7 @@
} }
var varTable = document.querySelector('table.variables'); var varTable = document.querySelector('table.variables');
var ws = new WebSocket("ws://localhost:8888", "myProtocol"); var ws = new WebSocket("ws://localhost:8888/api/ws/VariableServer", "myProtocol");
// WebSocket Event Handlers // WebSocket Event Handlers
ws.onopen = function(e) { ws.onopen = function(e) {

View File

@ -1,7 +1,32 @@
/************************************************************************* /*************************************************************************
PURPOSE: (Represent Websocket variable server connection.) PURPOSE: (Represent Websocket variable server connection.)
LIBRARY DEPENDENCIES: LIBRARY DEPENDENCIES:
( (../src/WSSession.o)) ( (../src/VariableServerSession.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"
"time" : <double>
"values" : []
}
**************************************************************************/ **************************************************************************/
#ifndef WSSESSION_HH #ifndef WSSESSION_HH
#define WSSESSION_HH #define WSSESSION_HH
@ -10,36 +35,32 @@ LIBRARY DEPENDENCIES:
#include <string> #include <string>
#include <mongoose.h> #include <mongoose.h>
#include "WebSocketSession.hh" #include "WebSocketSession.hh"
#include "WSSessionVariable.hh" #include "VariableServerVariable.hh"
class VariableServerSession : public WebSocketSession { class VariableServerSession : public WebSocketSession {
public: public:
VariableServerSession(struct mg_connection *nc); VariableServerSession(struct mg_connection *nc);
void stageData(); /* -- base */
void sendMessage(); /* -- base */
int handleMessage(std::string); /* -- base */
void stageData(); /* -- virtual base */ void setTimeInterval(unsigned int milliseconds);
void sendMessage(); /* -- virtual base */ void addVariable(char* vname);
int handleMessage(std::string); /* -- virtual base */ void stageVariableValues();
void pause();
void setTimeInterval(unsigned int milliseconds); /* -- VariableServerSession specific */ void unpause();
void addVariable(char* vname); /* -- VariableServerSession specific */ void clear();
void stageVariableValues(); /* -- VariableServerSession specific */ void exit();
void pause(); /* -- VariableServerSession specific */
void unpause(); /* -- VariableServerSession specific */
void clear(); /* -- VariableServerSession specific */
void exit(); /* -- VariableServerSession specific */
static int bad_ref_int ; static int bad_ref_int ;
private: private:
int sendErrorMessage(const char* fmt, ... ); int sendErrorMessage(const char* fmt, ... );
REF2* make_error_ref(const char* in_name);
//struct mg_connection* connection; /* -- Base */ double stageTime;
std::vector<VariableServerVariable*> sessionVariables;
REF2* make_error_ref(const char* in_name); /* -- VariableServerSession specific */ bool cyclicSendEnabled;
double stageTime; /* -- VariableServerSession specific */ long long nextTime;
std::vector<WSsessionVariable*> sessionVariables; /* -- VariableServerSession specific */ long long intervalTimeTics;
bool cyclicSendEnabled; /* -- VariableServerSession specific */
long long nextTime; /* -- VariableServerSession specific */
long long intervalTimeTics; /* -- VariableServerSession specific */
}; };
#endif #endif

View File

@ -1,10 +1,10 @@
/************************************************************************* /*************************************************************************
PURPOSE: (Represent Websocket variable server variable.) PURPOSE: (Represent Websocket variable server variable.)
LIBRARY DEPENDENCIES: LIBRARY DEPENDENCIES:
( (../src/WSSessionVariable.o)) ( (../src/VariableServerVariable.o))
**************************************************************************/ **************************************************************************/
#ifndef WSSESSIONVARIABLE_HH #ifndef VARIABLE_SERVER_VARIABLE_HH
#define WSSESSIONVARIABLE_HH #define VARIABLE_SERVER_VARIABLE_HH
#include <time.h> #include <time.h>
#include <vector> #include <vector>
@ -14,17 +14,17 @@ LIBRARY DEPENDENCIES:
#define MAX_ARRAY_LENGTH 4096 #define MAX_ARRAY_LENGTH 4096
class WSsessionVariable { class VariableServerVariable {
public: public:
WSsessionVariable( REF2* variableType); VariableServerVariable( REF2* variableType);
~WSsessionVariable(); ~VariableServerVariable();
const char* getName(); const char* getName();
void stageValue(); void stageValue();
void writeValue( std::ostream& chkpnt_os ); void writeValue( std::ostream& chkpnt_os );
private: private:
WSsessionVariable() {} VariableServerVariable() {}
REF2 *varInfo; REF2 *varInfo;
void *address; void *address;
int size; int size;

View File

@ -1,7 +1,5 @@
/************************************************************************* /*************************************************************************
PURPOSE: (Represent Websocket variable server connection.) PURPOSE: (Represent Websocket connection.)
LIBRARY DEPENDENCIES:
( (../src/WSSession.o))
**************************************************************************/ **************************************************************************/
#ifndef WEB_SOCKET_SESSION_HH #ifndef WEB_SOCKET_SESSION_HH
#define WEB_SOCKET_SESSION_HH #define WEB_SOCKET_SESSION_HH

View File

@ -1,21 +1,19 @@
/************************************************************************* /*************************************************************************
PURPOSE: (Represent the state and initial conditions of an http server) PURPOSE: (Represent the state and initial conditions of an http server.)
LIBRARY DEPENDENCIES: LIBRARY DEPENDENCIES:
( (../src/http_server.cpp)) ( (../src/http_server.cpp))
**************************************************************************/ **************************************************************************/
#ifndef HTTP_SERVER_H #ifndef HTTP_SERVER_H
#define HTTP_SERVER_H #define HTTP_SERVER_H
#include <sys/types.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <mongoose.h>
#include <pthread.h>
#include <string> #include <string>
#include <map> #include <map>
#include <mongoose.h>
#include <pthread.h>
#include "../include/WebSocketSession.hh" #include "../include/WebSocketSession.hh"
typedef void (*httpMethodHandler)(struct mg_connection *, struct http_message *); typedef void (*httpMethodHandler)(struct mg_connection *, struct http_message *);
typedef WebSocketSession* (*WebSocketSessionMaker)(struct mg_connection *nc);
class HTTP_Server { class HTTP_Server {
public: public:
@ -26,8 +24,10 @@ class HTTP_Server {
pthread_t server_thread; /* ** */ pthread_t server_thread; /* ** */
bool shutting_down; bool shutting_down;
std::map< std::string, httpMethodHandler> httpMethodHandlerMap; /* ** */ std::map< std::string, httpMethodHandler> httpGETHandlerMap; /* ** */
pthread_mutex_t APIMapLock; /* ** */ pthread_mutex_t httpGETHandlerMapLock; /* ** */
std::map< std::string, WebSocketSessionMaker> WebSocketSessionMakerMap; /* ** */
pthread_mutex_t WebSocketSessionMakerMapLock; /* ** */
std::map<mg_connection*, WebSocketSession*> sessionMap; /* ** */ std::map<mg_connection*, WebSocketSession*> sessionMap; /* ** */
pthread_mutex_t sessionMapLock; /* ** */ pthread_mutex_t sessionMapLock; /* ** */
struct mg_serve_http_opts http_server_options; /* ** mongoose*/ struct mg_serve_http_opts http_server_options; /* ** mongoose*/
@ -40,11 +40,16 @@ class HTTP_Server {
int http_top_of_frame(); int http_top_of_frame();
int http_shutdown(); int http_shutdown();
void sendSessionMessages(struct mg_connection *nc); void installWebSocketSessionMaker(std::string name, WebSocketSessionMaker creater);
void handleClientMessage(struct mg_connection *nc, std::string msg); void installHTTPGEThandler(std::string APIname, httpMethodHandler handler);
void addSession(struct mg_connection *nc, WebSocketSession* session);
void deleteSession(struct mg_connection *nc); // These are internals and should be considered public. They are not private only
void install_API_GET_handler(std::string APIname, httpMethodHandler handler); // because they need to be callable from the servers event handler.
void handle_API_GET_request(struct mg_connection *nc, http_message *hm, std::string handlerName); void sendWebSocketSessionMessages(struct mg_connection *nc);
void handleWebSocketClientMessage(struct mg_connection *nc, std::string msg);
void addWebSocketSession(struct mg_connection *nc, WebSocketSession* session);
void deleteWebSocketSession(struct mg_connection *nc);
WebSocketSession* makeWebSocketSession(struct mg_connection *nc, std::string name);
void handleHTTPGETrequest(struct mg_connection *nc, http_message *hm, std::string handlerName);
}; };
#endif #endif

View File

@ -1,7 +1,9 @@
/************************************************************************ /************************************************************************
PURPOSE: (Represent the state and initial conditions of an http server) PURPOSE: (Represent the state and initial conditions of an http server)
LIBRARY DEPENDENCIES: LIBRARY DEPENDENCIES:
((simpleJSON.o)) ((simpleJSON.o)
(VariableServerVariable.o)
)
**************************************************************************/ **************************************************************************/
#include <sstream> #include <sstream>
#include <iomanip> // for setprecision #include <iomanip> // for setprecision
@ -81,14 +83,14 @@ void VariableServerSession::addVariable(char* vname){
if ( new_ref != NULL ) { if ( new_ref != NULL ) {
// This REF2 object will "belong" to the VariableServerSessionVariable, so it has // This REF2 object will "belong" to the VariableServerSessionVariable, so it has
// the right and responsibility to free() it in its destructor. // the right and responsibility to free() it in its destructor.
WSsessionVariable *sessionVariable = new WSsessionVariable( new_ref ) ; VariableServerVariable *sessionVariable = new VariableServerVariable( new_ref ) ;
sessionVariables.push_back( sessionVariable ) ; sessionVariables.push_back( sessionVariable ) ;
} }
} }
void VariableServerSession::stageVariableValues() { void VariableServerSession::stageVariableValues() {
stageTime = (double)exec_get_time_tics() / exec_get_time_tic_value(); stageTime = (double)exec_get_time_tics() / exec_get_time_tic_value();
std::vector<WSsessionVariable*>::iterator it; std::vector<VariableServerVariable*>::iterator it;
for (it = sessionVariables.begin(); it != sessionVariables.end(); it++ ) { for (it = sessionVariables.begin(); it != sessionVariables.end(); it++ ) {
(*it)->stageValue(); (*it)->stageValue();
} }
@ -103,7 +105,7 @@ void VariableServerSession::stageData() {
} }
void VariableServerSession::sendMessage() { void VariableServerSession::sendMessage() {
std::vector<WSsessionVariable*>::iterator it; std::vector<VariableServerVariable*>::iterator it;
std::stringstream ss; std::stringstream ss;
ss << "{ \"msg_type\" : \"values\",\n"; ss << "{ \"msg_type\" : \"values\",\n";
@ -125,7 +127,7 @@ void VariableServerSession::pause() { cyclicSendEnabled = false; }
void VariableServerSession::unpause() { cyclicSendEnabled = true; } void VariableServerSession::unpause() { cyclicSendEnabled = true; }
void VariableServerSession::clear() { void VariableServerSession::clear() {
std::vector<WSsessionVariable*>::iterator it; std::vector<VariableServerVariable*>::iterator it;
it = sessionVariables.begin(); it = sessionVariables.begin();
while (it != sessionVariables.end()) { while (it != sessionVariables.end()) {
delete *it; delete *it;

View File

@ -1,9 +1,9 @@
#include "trick/memorymanager_c_intf.h" // for get_size. #include "trick/memorymanager_c_intf.h" // for get_size.
#include "../include/WSSessionVariable.hh" #include "../include/VariableServerVariable.hh"
#include <math.h> // for fpclassify #include <math.h> // for fpclassify
#include <iomanip> // for setprecision #include <iomanip> // for setprecision
WSsessionVariable::WSsessionVariable(REF2 * ref ) { VariableServerVariable::VariableServerVariable(REF2 * ref ) {
varInfo = ref; varInfo = ref;
address = varInfo->address; address = varInfo->address;
size = varInfo->attr->size ; size = varInfo->attr->size ;
@ -41,12 +41,12 @@ WSsessionVariable::WSsessionVariable(REF2 * ref ) {
stageBuffer = calloc(size, 1) ; stageBuffer = calloc(size, 1) ;
} }
WSsessionVariable::~WSsessionVariable() { VariableServerVariable::~VariableServerVariable() {
if (varInfo != NULL) free( varInfo ); if (varInfo != NULL) free( varInfo );
} }
const char* WSsessionVariable::getName() { const char* VariableServerVariable::getName() {
return varInfo->reference; return varInfo->reference;
} }
@ -66,7 +66,7 @@ static void write_quoted_str( std::ostream& os, const char* s) {
os << "\"" ; os << "\"" ;
} }
void WSsessionVariable::stageValue() { void VariableServerVariable::stageValue() {
// Copy <size> bytes from <address> to staging_point. // Copy <size> bytes from <address> to staging_point.
if ( varInfo->attr->type == TRICK_STRING ) { if ( varInfo->attr->type == TRICK_STRING ) {
@ -82,7 +82,7 @@ void WSsessionVariable::stageValue() {
} }
} }
void WSsessionVariable::writeValue( std::ostream& outs ) { void VariableServerVariable::writeValue( std::ostream& outs ) {
switch(varInfo->attr->type) { switch(varInfo->attr->type) {
case TRICK_UNSIGNED_CHARACTER: case TRICK_UNSIGNED_CHARACTER:

View File

@ -1,73 +1,51 @@
/************************************************************************ /************************************************************************
PURPOSE: (Represent the state and initial conditions of an http server) PURPOSE: (Represent the state and initial conditions of an http server)
LIBRARY DEPENDENCIES: LIBRARY DEPENDENCIES:
( ((VariableServerSession.o)
(VariableServerSession.o) (http_GET_handlers.o))
(WSSessionVariable.o)
(http_GET_handlers.o)
)
**************************************************************************/ **************************************************************************/
#include <iostream>
/*
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"
"time" : <double>
"values" : []
}
*/
#include "../include/http_server.hh" #include "../include/http_server.hh"
#include "../include/VariableServerSession.hh"
#include "../include/http_GET_handlers.hh" #include "../include/http_GET_handlers.hh"
#include "../include/VariableServerSession.hh"
static const struct mg_str s_get_method = MG_MK_STR("GET"); 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_delete_method = MG_MK_STR("DELETE"); static const struct mg_str s_delete_method = MG_MK_STR("DELETE");
static const struct mg_str api_prefix = MG_MK_STR("/api/v1/"); static const struct mg_str http_api_prefix = MG_MK_STR("/api/http/");
static const struct mg_str ws_api_prefix = MG_MK_STR("/api/ws/");
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) {
http_message *hm = (struct http_message *)ev_data; http_message *hm = (struct http_message *)ev_data;
HTTP_Server* hs = (HTTP_Server *)nc->user_data; HTTP_Server* httpServer = (HTTP_Server *)nc->user_data;
switch(ev) { switch(ev) {
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { // Process new websocket connection.
std::string uri(hm->uri.p, hm->uri.len); std::string uri(hm->uri.p, hm->uri.len);
std::cout << "WEBSOCKET_REQUEST: URI = \"" << uri << "\"" << std::endl;
if (mg_str_starts_with(hm->uri, ws_api_prefix)) {
std::string wsType (hm->uri.p + ws_api_prefix.len, hm->uri.len - ws_api_prefix.len);
WebSocketSession* session = httpServer->makeWebSocketSession(nc, wsType);
if (session != NULL) {
httpServer->addWebSocketSession(nc, session);
std::cout << "WEBSOCKET[" << (void*)nc << "] OPENED. URI=\"" << uri << "\"." << std::endl; std::cout << "WEBSOCKET[" << (void*)nc << "] OPENED. URI=\"" << uri << "\"." << std::endl;
// Create a session object to store information about this web-socket connection. } else {
WebSocketSession* session = new VariableServerSession(nc); nc->flags |= MG_F_SEND_AND_CLOSE;
hs->addSession(nc, session); std::cout << "ERROR: No such web socket interface: \"" << uri << "\"." << std::endl;
}
}
} break; } break;
case MG_EV_WEBSOCKET_FRAME: { // Process websocket messages from the client (web browser). case MG_EV_WEBSOCKET_FRAME: { // Process websocket messages from the client (web browser).
struct websocket_message *wm = (struct websocket_message *) ev_data; struct websocket_message *wm = (struct websocket_message *) ev_data;
std::string msg ((char*)wm->data, wm->size); std::string msg ((char*)wm->data, wm->size);
std::cout << "WEBSOCKET[" << (void*)nc << "] RECIEVED: " << msg << std::endl; std::cout << "WEBSOCKET[" << (void*)nc << "] RECIEVED: " << msg << std::endl;
if (nc->flags & MG_F_IS_WEBSOCKET) { if (nc->flags & MG_F_IS_WEBSOCKET) {
hs->handleClientMessage(nc, msg); httpServer->handleWebSocketClientMessage(nc, msg);
} }
} break; } break;
case MG_EV_CLOSE: { case MG_EV_CLOSE: { // Process closed websocket connection.
if (nc->flags & MG_F_IS_WEBSOCKET) { if (nc->flags & MG_F_IS_WEBSOCKET) {
hs->deleteSession(nc); httpServer->deleteWebSocketSession(nc);
std::cout << "WEBSOCKET[" << (void*)nc << "] CLOSED." << std::endl; std::cout << "WEBSOCKET[" << (void*)nc << "] CLOSED." << std::endl;
} }
} break; } break;
@ -76,16 +54,16 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
// called periodically by the threaded function connectionAttendant() [below]. // called periodically by the threaded function connectionAttendant() [below].
// Send websocket messages to the client (web browser). // Send websocket messages to the client (web browser).
if (nc->flags & MG_F_IS_WEBSOCKET) { if (nc->flags & MG_F_IS_WEBSOCKET) {
hs->sendSessionMessages(nc); httpServer->sendWebSocketSessionMessages(nc);
} }
} break; } break;
case MG_EV_HTTP_REQUEST: { case MG_EV_HTTP_REQUEST: { // Process HTTP requests.
std::string uri(hm->uri.p, hm->uri.len); std::string uri(hm->uri.p, hm->uri.len);
std::cout << "HTTP_REQUEST: URI = \"" << uri << "\"" << std::endl; std::cout << "HTTP_REQUEST: URI = \"" << uri << "\"" << std::endl;
if (mg_str_starts_with(hm->uri, api_prefix)) { if (mg_str_starts_with(hm->uri, http_api_prefix)) {
if (mg_strcmp(hm->method, s_get_method)==0) { if (mg_strcmp(hm->method, s_get_method)==0) {
std::string handlerName (hm->uri.p + api_prefix.len, hm->uri.len - api_prefix.len); std::string handlerName (hm->uri.p + http_api_prefix.len, hm->uri.len - http_api_prefix.len);
hs->handle_API_GET_request(nc, hm, handlerName); httpServer->handleHTTPGETrequest(nc, hm, handlerName);
} else if (mg_strcmp(hm->method, s_put_method)==0) { } else if (mg_strcmp(hm->method, s_put_method)==0) {
mg_http_send_error(nc, 405, "PUT method not allowed."); mg_http_send_error(nc, 405, "PUT method not allowed.");
} else if (mg_strcmp(hm->method, s_delete_method)==0) { } else if (mg_strcmp(hm->method, s_delete_method)==0) {
@ -93,7 +71,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
} }
} else { } else {
// Serve the files in the document-root directory, as specified by the URI. // Serve the files in the document-root directory, as specified by the URI.
mg_serve_http(nc, (struct http_message *) ev_data, hs->http_server_options); mg_serve_http(nc, (struct http_message *) ev_data, httpServer->http_server_options);
} }
} break; } break;
default: { default: {
@ -121,16 +99,34 @@ static void* connectionAttendant (void* arg) {
return NULL; return NULL;
} }
void HTTP_Server::install_API_GET_handler(std::string APIname, httpMethodHandler handler) { void HTTP_Server::installWebSocketSessionMaker(std::string name, WebSocketSessionMaker maker) {
pthread_mutex_lock(&APIMapLock); pthread_mutex_lock(&WebSocketSessionMakerMapLock);
httpMethodHandlerMap.insert(std::pair<std::string, httpMethodHandler>(APIname, handler)); WebSocketSessionMakerMap.insert(std::pair<std::string, WebSocketSessionMaker>(name, maker));
pthread_mutex_unlock(&APIMapLock); pthread_mutex_unlock(&WebSocketSessionMakerMapLock);
} }
void HTTP_Server::handle_API_GET_request(struct mg_connection *nc, http_message *hm, std::string handlerName) { WebSocketSession* HTTP_Server::makeWebSocketSession(struct mg_connection *nc, std::string name) {
std::map<std::string, WebSocketSessionMaker>::iterator iter;
iter = WebSocketSessionMakerMap.find(name);
if (iter != WebSocketSessionMakerMap.end()) {
WebSocketSessionMaker maker = iter->second;
return maker(nc);
} else {
return NULL;
mg_http_send_error(nc, 404, "No such API.");
}
}
void HTTP_Server::installHTTPGEThandler(std::string APIname, httpMethodHandler handler) {
pthread_mutex_lock(&httpGETHandlerMapLock);
httpGETHandlerMap.insert(std::pair<std::string, httpMethodHandler>(APIname, handler));
pthread_mutex_unlock(&httpGETHandlerMapLock);
}
void HTTP_Server::handleHTTPGETrequest(struct mg_connection *nc, http_message *hm, std::string handlerName) {
std::map<std::string, httpMethodHandler>::iterator iter; std::map<std::string, httpMethodHandler>::iterator iter;
iter = httpMethodHandlerMap.find(handlerName); iter = httpGETHandlerMap.find(handlerName);
if (iter != httpMethodHandlerMap.end()) { if (iter != httpGETHandlerMap.end()) {
httpMethodHandler handler = iter->second; httpMethodHandler handler = iter->second;
handler(nc, hm); handler(nc, hm);
} else { } else {
@ -138,7 +134,7 @@ void HTTP_Server::handle_API_GET_request(struct mg_connection *nc, http_message
} }
} }
void HTTP_Server::sendSessionMessages(struct mg_connection *nc) { void HTTP_Server::sendWebSocketSessionMessages(struct mg_connection *nc) {
// Find the session that goes with the given websocket connection, // Find the session that goes with the given websocket connection,
// and tell it to send its values to the client (web browser). // and tell it to send its values to the client (web browser).
std::map<mg_connection*, WebSocketSession*>::iterator iter; std::map<mg_connection*, WebSocketSession*>::iterator iter;
@ -149,7 +145,7 @@ void HTTP_Server::sendSessionMessages(struct mg_connection *nc) {
} }
} }
void HTTP_Server::deleteSession(struct mg_connection *nc) { void HTTP_Server::deleteWebSocketSession(struct mg_connection *nc) {
std::map<mg_connection*, WebSocketSession*>::iterator iter; std::map<mg_connection*, WebSocketSession*>::iterator iter;
iter = sessionMap.find(nc); iter = sessionMap.find(nc);
if (iter != sessionMap.end()) { if (iter != sessionMap.end()) {
@ -158,7 +154,7 @@ void HTTP_Server::deleteSession(struct mg_connection *nc) {
sessionMap.erase(iter); sessionMap.erase(iter);
} }
} }
void HTTP_Server::handleClientMessage(struct mg_connection *nc, std::string msg) { void HTTP_Server::handleWebSocketClientMessage(struct mg_connection *nc, std::string msg) {
std::map<mg_connection*, WebSocketSession*>::iterator iter; std::map<mg_connection*, WebSocketSession*>::iterator iter;
iter = sessionMap.find(nc); iter = sessionMap.find(nc);
if (iter != sessionMap.end()) { if (iter != sessionMap.end()) {
@ -167,7 +163,7 @@ void HTTP_Server::handleClientMessage(struct mg_connection *nc, std::string msg)
} }
} }
void HTTP_Server::addSession(struct mg_connection *nc, WebSocketSession* session) { void HTTP_Server::addWebSocketSession(struct mg_connection *nc, WebSocketSession* session) {
pthread_mutex_lock(&sessionMapLock); pthread_mutex_lock(&sessionMapLock);
sessionMap.insert( std::pair<mg_connection*, WebSocketSession*>(nc, session) ); sessionMap.insert( std::pair<mg_connection*, WebSocketSession*>(nc, session) );
pthread_mutex_unlock(&sessionMapLock); pthread_mutex_unlock(&sessionMapLock);
@ -184,13 +180,19 @@ int HTTP_Server::http_default_data() {
return 0; return 0;
} }
static WebSocketSession* makeVariableServerSession( struct mg_connection *nc ) {
return new VariableServerSession(nc);
}
int HTTP_Server::http_init() { int HTTP_Server::http_init() {
http_server_options.document_root = document_root; http_server_options.document_root = document_root;
http_server_options.enable_directory_listing = "yes"; http_server_options.enable_directory_listing = "yes";
install_API_GET_handler("vs_connections", &handle_HTTP_GET_vs_connections); installHTTPGEThandler("vs_connections", &handle_HTTP_GET_vs_connections);
install_API_GET_handler("alloc_info", &handle_HTTP_GET_alloc_info); installHTTPGEThandler("alloc_info", &handle_HTTP_GET_alloc_info);
installWebSocketSessionMaker("VariableServer", &makeVariableServerSession);
//installWebSocketSessionMaker("VariableServer", [](struct mg_connection *nc) -> WebSocketSession* { return new VariableServerSession(nc); } );
mg_mgr_init( &mgr, NULL ); mg_mgr_init( &mgr, NULL );