Small refactor and interface update
This commit is contained in:
@@ -4,32 +4,20 @@ CONFIG -= app_bundle
|
|||||||
CONFIG -= qt
|
CONFIG -= qt
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
uSockets/src/eventing/epoll.c \
|
uSockets/src/eventing/epoll.c \
|
||||||
uSockets/src/context.c \
|
uSockets/src/context.c \
|
||||||
uSockets/src/socket.c \
|
uSockets/src/socket.c \
|
||||||
uSockets/src/eventing/libuv.c \
|
uSockets/src/eventing/libuv.c \
|
||||||
uSockets/src/ssl.c \
|
uSockets/src/ssl.c \
|
||||||
uSockets/src/loop.c
|
uSockets/src/loop.c
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/Hub.h \
|
src/Http.h \
|
||||||
src/Http.h \
|
src/uWS.h \
|
||||||
src/Context.h \
|
src/HttpRouter.h \
|
||||||
src/uWS.h \
|
src/Loop.h \
|
||||||
src/HttpRouter.h
|
src/App.h
|
||||||
#uSockets/libusockets.h \
|
|
||||||
#uSockets/internal/eventing/epoll.h \
|
|
||||||
#uSockets/internal/networking/bsd.h \
|
|
||||||
#uSockets/internal/eventing/libuv.h \
|
|
||||||
#uSockets/internal/common.h \
|
|
||||||
#uSockets/interfaces/timer.h \
|
|
||||||
#uSockets/interfaces/socket.h \
|
|
||||||
#uSockets/interfaces/poll.h \
|
|
||||||
#uSockets/interfaces/context.h \
|
|
||||||
#uSockets/interfaces/loop.h \
|
|
||||||
#uSockets/interfaces/ssl.h \
|
|
||||||
#uSockets/internal/loop.h
|
|
||||||
|
|
||||||
INCLUDEPATH += uSockets/src src
|
INCLUDEPATH += uSockets/src src
|
||||||
#QMAKE_CXXFLAGS += -fsanitize=address
|
#QMAKE_CXXFLAGS += -fsanitize=address
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// this is roughly the interfaces I plan for (with changes and additional helpers added with time)
|
// this is roughly the interfaces I plan for (with changes and additional helpers added with time)
|
||||||
// much speaks for a header-only or header-mostly implementation now that uSockets is properly isolating its internal headers
|
// much speaks for a header-only or header-mostly implementation now that uSockets is properly isolating its internal headers
|
||||||
|
|
||||||
#include "Context.h"
|
#include "App.h"
|
||||||
#include "HttpRouter.h"
|
#include "HttpRouter.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@@ -9,24 +9,23 @@ int main() {
|
|||||||
std::cout << "HttpSocket size: " << sizeof(HttpSocket<true>::Data) << std::endl;
|
std::cout << "HttpSocket size: " << sizeof(HttpSocket<true>::Data) << std::endl;
|
||||||
char *buffer = new char[512];
|
char *buffer = new char[512];
|
||||||
|
|
||||||
// SSL options are given via uSockets structure
|
uWS::SSLApp c(uWS::SSLOptions()
|
||||||
us_ssl_socket_context_options options = {};
|
.keyFileName("/home/alexhultman/uWebSockets/misc/ssl/key.pem")
|
||||||
options.key_file_name = "/home/alexhultman/uWebSockets/misc/ssl/key.pem";
|
.certFileName("/home/alexhultman/uWebSockets/misc/ssl/cert.pem")
|
||||||
options.cert_file_name = "/home/alexhultman/uWebSockets/misc/ssl/cert.pem";
|
.passphrase("1234"));
|
||||||
options.passphrase = "1234";
|
//uWS::App c;
|
||||||
|
|
||||||
//uWS::SSLContext c(options);
|
c.onGet("/", [buffer](auto *s, HttpRequest *req, auto *args) {
|
||||||
uWS::Context c;
|
|
||||||
|
|
||||||
c.route("GET", "/", [buffer](auto *s, HttpRequest *req, auto *args) {
|
|
||||||
|
|
||||||
s->writeStatus(200)->writeHeader("Hello", "World")->end(buffer, 512);
|
s->writeStatus(200)->writeHeader("Hello", "World")->end(buffer, 512);
|
||||||
|
|
||||||
}).route("GET", "/wrong", [buffer](auto *s, HttpRequest *req, auto *args) {
|
}).onGet("/wrong", [buffer](auto *s, HttpRequest *req, auto *args) {
|
||||||
|
|
||||||
std::cout << "Wrong way!" << std::endl;
|
std::cout << "Wrong way!" << std::endl;
|
||||||
|
|
||||||
|
}).onWebSocket([]() {
|
||||||
|
|
||||||
}).listen("localhost", 3000, 0);
|
}).listen("localhost", 3000, 0);
|
||||||
|
|
||||||
uWS::defaultHub.run();
|
uWS::run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,181 @@
|
|||||||
|
#ifndef CONTEXT_H
|
||||||
|
#define CONTEXT_H
|
||||||
|
|
||||||
|
#include "libusockets.h"
|
||||||
|
#include <type_traits>
|
||||||
|
#include "Loop.h"
|
||||||
|
#include "Http.h"
|
||||||
|
#include "HttpRouter.h"
|
||||||
|
|
||||||
|
namespace uWS {
|
||||||
|
|
||||||
|
template <bool SSL>
|
||||||
|
class AppBase {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
static constexpr typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
||||||
|
if constexpr(SSL) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename std::conditional<SSL, us_ssl_socket_context, us_socket_context>::type SOCKET_CONTEXT_TYPE;
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
Data() {
|
||||||
|
|
||||||
|
// default http handler is a router
|
||||||
|
onHttpRequest = [this](auto *s, HttpRequest *req) {
|
||||||
|
UserData user = {s, req};
|
||||||
|
r.route("GET", 3, req->getUrl().data(), req->getUrl().length(), &user);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UserData {
|
||||||
|
HttpSocket<SSL> *httpSocket;
|
||||||
|
HttpRequest *httpRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpRouter<UserData *> r;
|
||||||
|
|
||||||
|
std::function<void(HttpSocket<SSL> *)> onHttpConnection;
|
||||||
|
std::function<void(HttpSocket<SSL> *)> onHttpDisconnection;
|
||||||
|
std::function<void(HttpSocket<SSL> *, HttpRequest *)> onHttpRequest;
|
||||||
|
} *data;
|
||||||
|
|
||||||
|
// server protocols
|
||||||
|
SOCKET_CONTEXT_TYPE *httpServerContext;
|
||||||
|
SOCKET_CONTEXT_TYPE *webSocketServerContext;
|
||||||
|
|
||||||
|
// a us_socket_context can be constructed from another us_socket_context and will then act purely as a behavior (shared SSL_CTX)
|
||||||
|
// only socket contexts that come from construction from the start can be listened or connected to
|
||||||
|
|
||||||
|
// us_create_derived_socket_context(us_socket_context)
|
||||||
|
|
||||||
|
// client protocols
|
||||||
|
|
||||||
|
void init(us_loop *loop) {
|
||||||
|
new (data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(httpServerContext)) Data();
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_open, us_socket_context_on_open)(httpServerContext, [](auto *s) {
|
||||||
|
Data *data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s));
|
||||||
|
|
||||||
|
// here we need to construct a HTTP socket on the ext!
|
||||||
|
|
||||||
|
if (!data->onHttpConnection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->onHttpConnection((HttpSocket<SSL> *) s);
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(httpServerContext, [](auto *s) {
|
||||||
|
Data *data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s));
|
||||||
|
|
||||||
|
if (!data->onHttpDisconnection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->onHttpDisconnection((HttpSocket<SSL> *) s);
|
||||||
|
});
|
||||||
|
|
||||||
|
static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(httpServerContext, [](auto *s, char *data, int length) {
|
||||||
|
|
||||||
|
Data *contextData = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s));
|
||||||
|
|
||||||
|
// a HttpSocket is basically the Http state and everything needed for it, we use it to parse the data and it knows about its context
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
HttpRequest req(data, length);
|
||||||
|
if (req.isComplete()) {
|
||||||
|
contextData->onHttpRequest((HttpSocket<SSL> *) s, &req);
|
||||||
|
} else {
|
||||||
|
std::cout << "Got chunked HTTP headers!" << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// for server
|
||||||
|
void listen(const char *host, int port, int options) {
|
||||||
|
static_dispatch(us_ssl_socket_context_listen, us_socket_context_listen)(httpServerContext, host, port, options, sizeof(HttpSocket<SSL>));
|
||||||
|
}
|
||||||
|
|
||||||
|
AppBase &onPost(std::string pattern, std::function<void(HttpSocket<SSL> *, HttpRequest *, std::vector<std::string_view> *)> handler) {
|
||||||
|
data->r.add("POST", pattern.c_str(), [handler](typename Data::UserData *user, auto *args) {
|
||||||
|
handler(user->httpSocket, user->httpRequest, args);
|
||||||
|
});
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppBase &onGet(std::string pattern, std::function<void(HttpSocket<SSL> *, HttpRequest *, std::vector<std::string_view> *)> handler) {
|
||||||
|
data->r.add("GET", pattern.c_str(), [handler](typename Data::UserData *user, auto *args) {
|
||||||
|
handler(user->httpSocket, user->httpRequest, args);
|
||||||
|
});
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for client and server
|
||||||
|
AppBase &onWebSocket(std::function<void()> handler) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~AppBase() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class App : public AppBase<false> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
App() {
|
||||||
|
httpServerContext = us_create_socket_context(defaultLoop.loop, sizeof(Data));
|
||||||
|
init(defaultLoop.loop);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SSLOptions {
|
||||||
|
public:
|
||||||
|
us_ssl_socket_context_options options = {};
|
||||||
|
|
||||||
|
SSLOptions() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SSLOptions &keyFileName(std::string fileName) {
|
||||||
|
options.key_file_name = fileName.c_str();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSLOptions &certFileName(std::string fileName) {
|
||||||
|
options.cert_file_name = fileName.c_str();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSLOptions &passphrase(std::string passphrase) {
|
||||||
|
options.passphrase = passphrase.c_str();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SSLApp : public AppBase<true> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
SSLApp(SSLOptions &sslOptions) {
|
||||||
|
httpServerContext = us_create_ssl_socket_context(defaultLoop.loop, sizeof(Data), sslOptions.options);
|
||||||
|
init(defaultLoop.loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONTEXT_H
|
||||||
-204
@@ -1,204 +0,0 @@
|
|||||||
#ifndef CONTEXT_H
|
|
||||||
#define CONTEXT_H
|
|
||||||
|
|
||||||
#include "Hub.h"
|
|
||||||
|
|
||||||
#include "libusockets.h"
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
// represents a mix of two us_socket contexts either in ssl or not (one for http, one for websocket)
|
|
||||||
|
|
||||||
// if you want to share the same openssl context between the two us socket ssl contexts? how?
|
|
||||||
|
|
||||||
#include "Http.h"
|
|
||||||
|
|
||||||
#include "HttpRouter.h"
|
|
||||||
|
|
||||||
namespace uWS {
|
|
||||||
|
|
||||||
// holds 4 protocols: server http, client http, server websocket, client websocket (for either SSL or not)
|
|
||||||
template <bool SSL>
|
|
||||||
class ContextBase {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
template <class A, class B>
|
|
||||||
static typename std::conditional<SSL, A, B>::type *static_dispatch(A *a, B *b) {
|
|
||||||
if constexpr(SSL) {
|
|
||||||
return a;
|
|
||||||
} else {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef typename std::conditional<SSL, us_ssl_socket_context, us_socket_context>::type SOCKET_CONTEXT_TYPE;
|
|
||||||
|
|
||||||
struct Data {
|
|
||||||
Data() {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::function<void(HttpSocket<SSL> *)> onHttpConnection;
|
|
||||||
std::function<void(HttpSocket<SSL> *)> onHttpDisconnection;
|
|
||||||
std::function<void(HttpSocket<SSL> *, HttpRequest *)> onHttpRequest;
|
|
||||||
} *data;
|
|
||||||
|
|
||||||
// server protocols
|
|
||||||
SOCKET_CONTEXT_TYPE *httpServerContext;
|
|
||||||
SOCKET_CONTEXT_TYPE *webSocketServerContext;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// client protocols
|
|
||||||
|
|
||||||
// we have a router too
|
|
||||||
struct UserData {
|
|
||||||
// pass whatever you need as user data
|
|
||||||
HttpSocket<SSL> *httpSocket;
|
|
||||||
HttpRequest *httpRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
HttpRouter<UserData *> r;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// the shared constructor
|
|
||||||
void init(us_loop *loop) {
|
|
||||||
|
|
||||||
new (data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(httpServerContext)) Data();
|
|
||||||
|
|
||||||
// register shims
|
|
||||||
static_dispatch(us_ssl_socket_context_on_open, us_socket_context_on_open)(httpServerContext, [](auto *s) {
|
|
||||||
Data *data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s));
|
|
||||||
|
|
||||||
|
|
||||||
// here we need to construct a HTTP socket on the ext!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// we always give pointers to us_socket?
|
|
||||||
// same mistake as before?
|
|
||||||
|
|
||||||
if (!data->onHttpConnection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: this is VERY tricky to keep bug-free!
|
|
||||||
// we could give the ext here, and skip all bugs?
|
|
||||||
data->onHttpConnection((HttpSocket<SSL> *) s);
|
|
||||||
});
|
|
||||||
|
|
||||||
static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(httpServerContext, [](auto *s) {
|
|
||||||
Data *data = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s));
|
|
||||||
|
|
||||||
|
|
||||||
// we always give pointers to us_socket?
|
|
||||||
// same mistake as before?
|
|
||||||
|
|
||||||
if (!data->onHttpDisconnection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: this is VERY tricky to keep bug-free!
|
|
||||||
// we could give the ext here, and skip all bugs?
|
|
||||||
data->onHttpDisconnection((HttpSocket<SSL> *) s);
|
|
||||||
});
|
|
||||||
|
|
||||||
static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(httpServerContext, [](auto *s, char *data, int length) {
|
|
||||||
|
|
||||||
Data *contextData = (Data *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)(static_dispatch(us_ssl_socket_get_context, us_socket_get_context)(s));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// a HttpSocket is basically the Http state and everything needed for it, we use it to parse the data and it knows about its context
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
HttpRequest req(data, length);
|
|
||||||
if (req.isComplete()) {
|
|
||||||
contextData->onHttpRequest((HttpSocket<SSL> *) s, &req);
|
|
||||||
} else {
|
|
||||||
std::cout << "Got chunked HTTP headers!" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// here we run the HTTP parser on this data
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// we always give pointers to us_socket?
|
|
||||||
// same mistake as before?
|
|
||||||
|
|
||||||
// note: this is VERY tricky to keep bug-free!
|
|
||||||
// we could give the ext here, and skip all bugs?
|
|
||||||
//data->((HttpSocket *) s);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// for server
|
|
||||||
void listen(const char *host, int port, int options) {
|
|
||||||
static_dispatch(us_ssl_socket_context_listen, us_socket_context_listen)(httpServerContext, host, port, options, sizeof(HttpSocket<SSL>));
|
|
||||||
}
|
|
||||||
|
|
||||||
// for server
|
|
||||||
ContextBase &onHttpRequest(decltype(Data::onHttpRequest) handler) {
|
|
||||||
data->onHttpRequest = handler;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ContextBase &route(std::string method, std::string pattern, std::function<void(HttpSocket<SSL> *, HttpRequest *, std::vector<std::string_view> *)> handler) {
|
|
||||||
// calling this function overrides any other onHttpRequest!
|
|
||||||
onHttpRequest([this](auto *s, HttpRequest *req) {
|
|
||||||
UserData user = {s, req};
|
|
||||||
r.route("GET", 3, req->getUrl().data(), req->getUrl().length(), &user);
|
|
||||||
});
|
|
||||||
|
|
||||||
r.add(method.c_str(), pattern.c_str(), [handler](UserData *user, auto *args) {
|
|
||||||
handler(user->httpSocket, user->httpRequest, args);
|
|
||||||
});
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for client and server
|
|
||||||
ContextBase &onWebSocketConnection() {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ContextBase() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Context : public ContextBase<false> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
Context() {
|
|
||||||
|
|
||||||
// we create the context ourselves here
|
|
||||||
httpServerContext = us_create_socket_context(defaultHub.loop, sizeof(Data));
|
|
||||||
|
|
||||||
// init from base
|
|
||||||
init(defaultHub.loop);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SSLContext : public ContextBase<true> {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// denna finns i barnet SSLContext!
|
|
||||||
SSLContext(us_ssl_socket_context_options options) {
|
|
||||||
// we create the context ourselves here
|
|
||||||
httpServerContext = us_create_ssl_socket_context(defaultHub.loop, sizeof(Data), options);
|
|
||||||
|
|
||||||
// init from base
|
|
||||||
init(defaultHub.loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CONTEXT_H
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
// should lie in hub and be connected with pre/post callbacks
|
|
||||||
char *corkBuffer = new char[1024];
|
|
||||||
int corkOffset = 0;
|
|
||||||
|
|
||||||
#ifndef HUB_H
|
|
||||||
#define HUB_H
|
|
||||||
|
|
||||||
#include "libusockets.h"
|
|
||||||
#include <functional>
|
|
||||||
#include <new>
|
|
||||||
#include <string_view>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "Http.h"
|
|
||||||
#include "Context.h"
|
|
||||||
|
|
||||||
struct Hub;
|
|
||||||
|
|
||||||
// Hub::listen has to create the socket context (with SSL options) via first time init
|
|
||||||
// what if you want to listen to another port with another SSL cert?
|
|
||||||
// every listen has to correspond to a listen socket and a socket context, created for each call to listen
|
|
||||||
// same with connect?
|
|
||||||
|
|
||||||
// just remove Context altogether and just let Hub have all of this stuff
|
|
||||||
// it really only needs to hold the listen socket and the socket context wrapped as ListenToken instead
|
|
||||||
// ListenToken.close()
|
|
||||||
|
|
||||||
// ListenContext?
|
|
||||||
|
|
||||||
|
|
||||||
// instead of Context, have some kind of token for Listening and allow it to be stopped but not cloesed (you stop listening but keep sockets alive)
|
|
||||||
// what if you then want to listen again? you don't want to create a new context that time?
|
|
||||||
|
|
||||||
// imagine listening, then stopping, then continuing - maybe support PAUSING a listen socket without closing it? that way you listen once, pause listening, etc
|
|
||||||
// this way we can solve the accept issue with listen-pause and listen timers?
|
|
||||||
|
|
||||||
// ListenToken.pause(), .resume(), .close()
|
|
||||||
|
|
||||||
|
|
||||||
// eller så bara ändrar man gränssnittet så att man explicit skapar ett context?
|
|
||||||
|
|
||||||
|
|
||||||
// createContext(ssl options eller inga options avgör om SSL eller inte)
|
|
||||||
// eller bara sslContext(options).onHttplalala.listen().Hub().run();
|
|
||||||
|
|
||||||
// hubben är underförstådd och du agerar egentligen alltid på ett context som antingen är ssl eller inte
|
|
||||||
|
|
||||||
struct Hub {
|
|
||||||
us_loop *loop;
|
|
||||||
|
|
||||||
struct Data {
|
|
||||||
Data() {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} *data;
|
|
||||||
|
|
||||||
static void wakeupCb(us_loop *loop) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void preCb(us_loop *loop) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void postCb(us_loop *loop) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Hub() : loop(us_create_loop(wakeupCb, preCb, postCb, sizeof(Data))) {
|
|
||||||
new (data = (Data *) us_loop_ext(loop)) Data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void run() {
|
|
||||||
us_loop_run(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Hub() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace uWS {
|
|
||||||
thread_local Hub defaultHub;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HUB_H
|
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// should lie in hub and be connected with pre/post callbacks
|
||||||
|
char *corkBuffer = new char[1024];
|
||||||
|
int corkOffset = 0;
|
||||||
|
|
||||||
|
#ifndef HUB_H
|
||||||
|
#define HUB_H
|
||||||
|
|
||||||
|
#include "libusockets.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <new>
|
||||||
|
#include <string_view>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace uWS {
|
||||||
|
struct Loop {
|
||||||
|
us_loop *loop;
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
Data() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} *data;
|
||||||
|
|
||||||
|
static void wakeupCb(us_loop *loop) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void preCb(us_loop *loop) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void postCb(us_loop *loop) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loop() : loop(us_create_loop(wakeupCb, preCb, postCb, sizeof(Data))) {
|
||||||
|
new (data = (Data *) us_loop_ext(loop)) Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
us_loop_run(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Loop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// dessa måste ligga i en sourcefil
|
||||||
|
thread_local Loop defaultLoop;
|
||||||
|
|
||||||
|
static void run() {
|
||||||
|
defaultLoop.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HUB_H
|
||||||
Reference in New Issue
Block a user