#include "App.h" #include #include "Utilities.h" using namespace v8; /* todo: probably isCorked, cork should be exposed? */ struct WebSocketWrapper { static Persistent wsTemplate[2]; template static inline uWS::WebSocket *getWebSocket(const FunctionCallbackInfo &args) { auto *ws = (uWS::WebSocket *) args.Holder()->GetAlignedPointerFromInternalField(0); if (!ws) { args.GetReturnValue().Set(isolate->ThrowException(String::NewFromUtf8(isolate, "Invalid access of closed uWS.WebSocket/SSLWebSocket."))); } return ws; } static inline void invalidateWsObject(const FunctionCallbackInfo &args) { args.Holder()->SetAlignedPointerInInternalField(0, nullptr); } /* Takes code, message, returns undefined */ template static void uWS_WebSocket_close(const FunctionCallbackInfo &args) { auto *ws = getWebSocket(args); if (ws) { int code = 0; if (args.Length() >= 1) { code = args[0]->Uint32Value(); } NativeString message(args.GetIsolate(), args[1]); if (message.isInvalid(args)) { return; } invalidateWsObject(args); ws->close(code, message.getString()); } } /* Takes nothing, returns integer */ template static void uWS_WebSocket_getBufferedAmount(const FunctionCallbackInfo &args) { auto *ws = getWebSocket(args); if (ws) { int bufferedAmount = ws->getBufferedAmount(); args.GetReturnValue().Set(Integer::New(isolate, bufferedAmount)); } } /* Takes message, isBinary. Returns true on success, false otherwise */ template static void uWS_WebSocket_send(const FunctionCallbackInfo &args) { auto *ws = getWebSocket(args); if (ws) { NativeString message(args.GetIsolate(), args[0]); if (message.isInvalid(args)) { return; } bool ok = ws->send(message.getString(), args[1]->BooleanValue() ? uWS::OpCode::BINARY : uWS::OpCode::TEXT); args.GetReturnValue().Set(Boolean::New(isolate, ok)); } } template static void initWsTemplate() { Local wsTemplateLocal = FunctionTemplate::New(isolate); if (SSL) { wsTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.SSLWebSocket")); } else { wsTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.WebSocket")); } wsTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1); /* Register our functions */ wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "send"), FunctionTemplate::New(isolate, uWS_WebSocket_send)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close"), FunctionTemplate::New(isolate, uWS_WebSocket_close)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getBufferedAmount"), FunctionTemplate::New(isolate, uWS_WebSocket_getBufferedAmount)); /* Create the template */ Local wsObjectLocal = wsTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); wsTemplate[SSL].Reset(isolate, wsObjectLocal); } /* This is where we output an instance */ template static Local getWsInstance() { return Local::New(isolate, wsTemplate[std::is_same::value])->Clone(); } }; /* Fix this, should be nicer */ Persistent WebSocketWrapper::wsTemplate[2];