diff --git a/src/AppWrapper.h b/src/AppWrapper.h index 290c7c5..dc6a11c 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -33,15 +33,8 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { /* idleTimeout */ behavior.idleTimeout = behaviorObject->Get(String::NewFromUtf8(isolate, "idleTimeout"))->Int32Value(); - /* Compression, map from 0, 1, 2 to disabled, shared, dedicated */ - int compression = behaviorObject->Get(String::NewFromUtf8(isolate, "compression"))->Int32Value(); - if (compression == 0) { - behavior.compression = uWS::CompressOptions::DISABLED; - } else if (compression == 1) { - behavior.compression = uWS::CompressOptions::SHARED_COMPRESSOR; - } else if (compression == 2) { - behavior.compression = uWS::CompressOptions::DEDICATED_COMPRESSOR; - } + /* Compression, map from 0, 1, 2 to disabled, shared, dedicated. This is actually the enum */ + behavior.compression = (uWS::CompressOptions) behaviorObject->Get(String::NewFromUtf8(isolate, "compression"))->Int32Value(); /* Open */ openPf.Reset(args.GetIsolate(), Local::Cast(behaviorObject->Get(String::NewFromUtf8(isolate, "open")))); @@ -53,6 +46,7 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { closePf.Reset(args.GetIsolate(), Local::Cast(behaviorObject->Get(String::NewFromUtf8(isolate, "close")))); } + /* Open handler is NOT optional for the wrapper */ behavior.open = [openPf = std::move(openPf)](auto *ws, auto *req) { HandleScope hs(isolate); @@ -69,34 +63,44 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { perSocketData->socketPf = new Persistent; perSocketData->socketPf->Reset(isolate, wsObject); - Local argv[] = {wsObject, reqObject}; - Local::New(isolate, openPf)->Call(isolate->GetCurrentContext()->Global(), 2, argv); + Local openLf = Local::New(isolate, openPf); + if (!openLf->IsUndefined()) { + Local argv[] = {wsObject, reqObject}; + openLf->Call(isolate->GetCurrentContext()->Global(), 2, argv); + } }; - behavior.message = [messagePf = std::move(messagePf)](auto *ws, std::string_view message, uWS::OpCode opCode) { - HandleScope hs(isolate); + /* Message handler is always optional */ + if (messagePf != Undefined(isolate)) { + behavior.message = [messagePf = std::move(messagePf)](auto *ws, std::string_view message, uWS::OpCode opCode) { + HandleScope hs(isolate); - Local messageArrayBuffer = ArrayBuffer::New(isolate, (void *) message.data(), message.length()); + Local messageArrayBuffer = ArrayBuffer::New(isolate, (void *) message.data(), message.length()); - PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); - Local argv[3] = {Local::New(isolate, *(perSocketData->socketPf)), - messageArrayBuffer, - Boolean::New(isolate, opCode == uWS::OpCode::BINARY)}; - Local::New(isolate, messagePf)->Call(isolate->GetCurrentContext()->Global(), 3, argv); + PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); + Local argv[3] = {Local::New(isolate, *(perSocketData->socketPf)), + messageArrayBuffer, + Boolean::New(isolate, opCode == uWS::OpCode::BINARY)}; + Local::New(isolate, messagePf)->Call(isolate->GetCurrentContext()->Global(), 3, argv); - /* Important: we clear the ArrayBuffer to make sure it is not invalidly used after return */ - messageArrayBuffer->Neuter(); - }; + /* Important: we clear the ArrayBuffer to make sure it is not invalidly used after return */ + messageArrayBuffer->Neuter(); + }; + } - behavior.drain = [drainPf = std::move(drainPf)](auto *ws) { - HandleScope hs(isolate); + /* Drain handler is always optional */ + if (drainPf != Undefined(isolate)) { + behavior.drain = [drainPf = std::move(drainPf)](auto *ws) { + HandleScope hs(isolate); - PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); - Local argv[1] = {Local::New(isolate, *(perSocketData->socketPf)) - }; - Local::New(isolate, drainPf)->Call(isolate->GetCurrentContext()->Global(), 1, argv); - }; + PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); + Local argv[1] = {Local::New(isolate, *(perSocketData->socketPf)) + }; + Local::New(isolate, drainPf)->Call(isolate->GetCurrentContext()->Global(), 1, argv); + }; + } + /* These are not hooked in */ behavior.ping = [](auto *ws) { }; @@ -105,19 +109,23 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { }; + /* Close handler is NOT optional for the wrapper */ behavior.close = [closePf = std::move(closePf)](auto *ws, int code, std::string_view message) { HandleScope hs(isolate); Local messageArrayBuffer = ArrayBuffer::New(isolate, (void *) message.data(), message.length()); PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); Local wsObject = Local::New(isolate, *(perSocketData->socketPf)); - Local argv[3] = {wsObject, - Integer::New(isolate, code), - messageArrayBuffer}; /* Invalidate this wsObject */ wsObject->SetAlignedPointerInInternalField(0, nullptr); - Local::New(isolate, closePf)->Call(isolate->GetCurrentContext()->Global(), 3, argv); + + /* Only call close handler if we have one set */ + Local closeLf = Local::New(isolate, closePf); + if (!closeLf->IsUndefined()) { + Local argv[3] = {wsObject, Integer::New(isolate, code), messageArrayBuffer}; + closeLf->Call(isolate->GetCurrentContext()->Global(), 3, argv); + } delete perSocketData->socketPf; diff --git a/src/addon.cpp b/src/addon.cpp index 8755096..64c5895 100644 --- a/src/addon.cpp +++ b/src/addon.cpp @@ -108,6 +108,11 @@ void Main(Local exports) { /* Expose some µSockets functions directly under uWS namespace */ exports->Set(String::NewFromUtf8(isolate, "us_listen_socket_close"), FunctionTemplate::New(isolate, uWS_us_listen_socket_close)->GetFunction()); + /* Compression enum */ + exports->Set(String::NewFromUtf8(isolate, "DISABLED"), Integer::NewFromUnsigned(isolate, uWS::DISABLED)); + exports->Set(String::NewFromUtf8(isolate, "SHARED_COMPRESSOR"), Integer::NewFromUnsigned(isolate, uWS::SHARED_COMPRESSOR)); + exports->Set(String::NewFromUtf8(isolate, "DEDICATED_COMPRESSOR"), Integer::NewFromUnsigned(isolate, uWS::DEDICATED_COMPRESSOR)); + /* The template for websockets */ WebSocketWrapper::initWsTemplate<0>(); WebSocketWrapper::initWsTemplate<1>(); diff --git a/tests/Autobahn.js b/tests/Autobahn.js index 2948dd9..9833ce7 100644 --- a/tests/Autobahn.js +++ b/tests/Autobahn.js @@ -14,16 +14,15 @@ function listenWithSettings(settings) { }; /* Create the app */ - let app = settings.ssl ? uWS.App(sslOptions) : uWS.SSLApp(sslOptions); + let app = settings.ssl ? uWS.SSLApp(sslOptions) : uWS.App(sslOptions); /* Attach our behavior from settings */ app.ws('/*', { compression: settings.compression, maxPayloadLength: 16 * 1024 * 1024, idleTimeout: 60, - message: (ws, message, isBinary) => { - ws.send(message, isBinary); + ws.send(message, isBinary, true); } }).any('/exit', (res, req) => { /* Shut down everything on this route */ @@ -56,21 +55,21 @@ function listenWithSettings(settings) { listenWithSettings({ port: 9001, ssl: false, - compression: 0 + compression: uWS.DISABLED }); /* SSL, shared compressor */ listenWithSettings({ port: 9002, ssl: true, - compression: 1 + compression: uWS.SHARED_COMPRESSOR }); /* non-SSL, dedicated compressor */ listenWithSettings({ port: 9003, ssl: false, - compression: 2 + compression: uWS.DEDICATED_COMPRESSOR }); /* This is required to check for memory leaks */ @@ -78,4 +77,4 @@ process.on('exit', () => { apps.forEach((a) => { a.app.forcefully_free(); }); -}); \ No newline at end of file +});