Here comes he RunT!
This commit is contained in:
230
Sources/websocket_v8_bindings.cpp
Normal file
230
Sources/websocket_v8_bindings.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
#include "websocket_v8_bindings.h"
|
||||
#include "websocket_bridge.h"
|
||||
#include <kinc/log.h>
|
||||
|
||||
using namespace v8;
|
||||
|
||||
void v8_runt_websocket_server_create(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() < 3 || !args[0]->IsString() || !args[1]->IsNumber() || !args[2]->IsNumber()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_create requires (host, port, maxConnections)").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
String::Utf8Value host(isolate, args[0]);
|
||||
int port = args[1]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
int maxConnections = args[2]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
|
||||
int serverId = runt_websocket_server_create(*host, port, maxConnections);
|
||||
args.GetReturnValue().Set(Integer::New(isolate, serverId));
|
||||
}
|
||||
|
||||
void v8_runt_websocket_server_start(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsNumber()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_start requires serverId").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
int serverId = args[0]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
bool success = runt_websocket_server_start(serverId);
|
||||
args.GetReturnValue().Set(Boolean::New(isolate, success));
|
||||
}
|
||||
|
||||
void v8_runt_websocket_server_stop(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsNumber()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_stop requires serverId").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
int serverId = args[0]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
runt_websocket_server_stop(serverId);
|
||||
args.GetReturnValue().Set(Undefined(isolate));
|
||||
}
|
||||
|
||||
void v8_runt_websocket_server_tick(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() < 1 || !args[0]->IsNumber()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_tick requires serverId").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
int serverId = args[0]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
runt_websocket_server_tick(serverId);
|
||||
args.GetReturnValue().Set(Undefined(isolate));
|
||||
}
|
||||
|
||||
void v8_runt_websocket_server_send_all(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() < 2 || !args[0]->IsNumber()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_send_all requires (serverId, data)").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
int serverId = args[0]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
|
||||
if (args[1]->IsArrayBuffer()) {
|
||||
Local<ArrayBuffer> buffer = args[1].As<ArrayBuffer>();
|
||||
void* data = buffer->GetBackingStore()->Data();
|
||||
size_t length = buffer->ByteLength();
|
||||
runt_websocket_server_send_all_binary(serverId, static_cast<const char*>(data), length);
|
||||
} else if (args[1]->IsArrayBufferView()) {
|
||||
Local<ArrayBufferView> view = args[1].As<ArrayBufferView>();
|
||||
Local<ArrayBuffer> buffer = view->Buffer();
|
||||
void* data = static_cast<char*>(buffer->GetBackingStore()->Data()) + view->ByteOffset();
|
||||
size_t length = view->ByteLength();
|
||||
runt_websocket_server_send_all_binary(serverId, static_cast<const char*>(data), length);
|
||||
} else if (args[1]->IsString()) {
|
||||
String::Utf8Value data(isolate, args[1]);
|
||||
runt_websocket_server_send_all(serverId, *data);
|
||||
} else {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_send_all data must be String or ArrayBuffer").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(Undefined(isolate));
|
||||
}
|
||||
|
||||
//#ifdef WITH_BENCHMARK
|
||||
//extern "C" {
|
||||
// void websocket_run_groupchat_test(int rate, int duration);
|
||||
// void websocket_run_benchmark();
|
||||
//}
|
||||
|
||||
//void v8_websocket_run_test(const FunctionCallbackInfo<Value>& args) {
|
||||
// Isolate* isolate = args.GetIsolate();
|
||||
// int rate = 60, duration = 5;
|
||||
// if (args.Length() >= 1 && args[0]->IsNumber()) {
|
||||
// rate = args[0]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
// }
|
||||
// if (args.Length() >= 2 && args[1]->IsNumber()) {
|
||||
// duration = args[1]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
// }
|
||||
// websocket_run_groupchat_test(rate, duration);
|
||||
//}
|
||||
|
||||
//void v8_websocket_run_benchmark(const FunctionCallbackInfo<Value>& args) {
|
||||
// websocket_run_benchmark();
|
||||
//}
|
||||
//#endif
|
||||
|
||||
void v8_runt_websocket_server_send_client(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() < 3 || !args[0]->IsNumber() || !args[1]->IsNumber()) {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_send_client requires (serverId, clientId, data)").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
int serverId = args[0]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
int clientId = args[1]->Int32Value(isolate->GetCurrentContext()).FromJust();
|
||||
|
||||
if (args[2]->IsArrayBuffer()) {
|
||||
Local<ArrayBuffer> buffer = args[2].As<ArrayBuffer>();
|
||||
void* data = buffer->GetBackingStore()->Data();
|
||||
size_t length = buffer->ByteLength();
|
||||
runt_websocket_server_send_client_binary(serverId, clientId, static_cast<const char*>(data), length);
|
||||
} else if (args[2]->IsArrayBufferView()) {
|
||||
Local<ArrayBufferView> view = args[2].As<ArrayBufferView>();
|
||||
Local<ArrayBuffer> buffer = view->Buffer();
|
||||
void* data = static_cast<char*>(buffer->GetBackingStore()->Data()) + view->ByteOffset();
|
||||
size_t length = view->ByteLength();
|
||||
runt_websocket_server_send_client_binary(serverId, clientId, static_cast<const char*>(data), length);
|
||||
} else if (args[2]->IsString()) {
|
||||
String::Utf8Value data(isolate, args[2]);
|
||||
runt_websocket_server_send_client(serverId, clientId, *data);
|
||||
} else {
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8(isolate, "runt_websocket_server_send_client data must be String or ArrayBuffer").ToLocalChecked()));
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(Undefined(isolate));
|
||||
}
|
||||
|
||||
void bind_websocket_bridge(Isolate* isolate, const Global<Context>& context) {
|
||||
// TODO: thread locking
|
||||
Locker locker{isolate};
|
||||
Isolate::Scope isolate_scope(isolate);
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
Local<Context> current_context = Local<Context>::New(isolate, context);
|
||||
Context::Scope context_scope(current_context);
|
||||
Local<Object> global = current_context->Global();
|
||||
|
||||
Local<Object> runt_obj;
|
||||
Local<Value> existing_runt = global->Get(current_context, String::NewFromUtf8(isolate, "RunT").ToLocalChecked()).ToLocalChecked();
|
||||
if (existing_runt->IsObject()) {
|
||||
runt_obj = existing_runt->ToObject(current_context).ToLocalChecked();
|
||||
} else {
|
||||
runt_obj = Object::New(isolate);
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "RunT").ToLocalChecked(), runt_obj);
|
||||
}
|
||||
|
||||
runt_obj->Set(current_context, String::NewFromUtf8(isolate, "websocketServerCreate").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_create).ToLocalChecked());
|
||||
|
||||
runt_obj->Set(current_context, String::NewFromUtf8(isolate, "websocketServerStart").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_start).ToLocalChecked());
|
||||
|
||||
runt_obj->Set(current_context, String::NewFromUtf8(isolate, "websocketServerStop").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_stop).ToLocalChecked());
|
||||
|
||||
runt_obj->Set(current_context, String::NewFromUtf8(isolate, "websocketServerTick").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_tick).ToLocalChecked());
|
||||
|
||||
runt_obj->Set(current_context, String::NewFromUtf8(isolate, "websocketServerSendAll").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_send_all).ToLocalChecked());
|
||||
|
||||
runt_obj->Set(current_context, String::NewFromUtf8(isolate, "websocketServerSendClient").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_send_client).ToLocalChecked());
|
||||
|
||||
// uWS compatibility aliases
|
||||
//runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerCreate").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_create).ToLocalChecked());
|
||||
//runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerDestroy").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_stop).ToLocalChecked());
|
||||
//runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerSend").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_send_all).ToLocalChecked());
|
||||
// runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerTick").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_tick).ToLocalChecked());
|
||||
//runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerSetOnConnection").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_start).ToLocalChecked());
|
||||
//runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerSetOnMessage").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_start).ToLocalChecked());
|
||||
//runt_obj->Set(current_context, String::NewFromUtf8(isolate, "uwsWebsocketServerSetOnDisconnection").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_runt_websocket_server_stop).ToLocalChecked());
|
||||
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "runt_websocket_server_create").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_create).ToLocalChecked());
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "runt_websocket_server_start").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_start).ToLocalChecked());
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "runt_websocket_server_stop").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_stop).ToLocalChecked());
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "runt_websocket_server_tick").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_tick).ToLocalChecked());
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "runt_websocket_server_send_all").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_send_all).ToLocalChecked());
|
||||
global->Set(current_context, String::NewFromUtf8(isolate, "runt_websocket_server_send_client").ToLocalChecked(),
|
||||
Function::New(current_context, v8_runt_websocket_server_send_client).ToLocalChecked());
|
||||
|
||||
//#ifdef WITH_BENCHMARK
|
||||
// global->Set(current_context, String::NewFromUtf8(isolate, "websocket_run_test").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_websocket_run_test).ToLocalChecked());
|
||||
// global->Set(current_context, String::NewFromUtf8(isolate, "websocket_run_benchmark").ToLocalChecked(),
|
||||
// Function::New(current_context, v8_websocket_run_benchmark).ToLocalChecked());
|
||||
//#endif
|
||||
}
|
||||
Reference in New Issue
Block a user