|
@ -12,83 +12,49 @@ |
|
|
|
|
|
|
|
|
using namespace v8; |
|
|
using namespace v8; |
|
|
|
|
|
|
|
|
static Persistent<String> readyState_str; |
|
|
static struct addrinfo tcp_hints = |
|
|
|
|
|
/* ai_flags */ { AI_PASSIVE |
|
|
static Persistent<Integer> readyStateCONNECTING; |
|
|
/* ai_family */ , AF_UNSPEC |
|
|
static Persistent<Integer> readyStateOPEN; |
|
|
/* ai_socktype */ , SOCK_STREAM |
|
|
static Persistent<Integer> readyStateCLOSED; |
|
|
/* ai_protocol */ , 0 |
|
|
|
|
|
/* ai_addrlen */ , 0 |
|
|
|
|
|
/* ai_addr */ , 0 |
|
|
|
|
|
/* ai_canonname */ , 0 |
|
|
|
|
|
/* ai_next */ , 0 |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
enum encoding {UTF8, RAW}; |
|
|
|
|
|
|
|
|
|
|
|
class Socket { |
|
|
class Socket { |
|
|
public: |
|
|
public: |
|
|
Socket (Handle<Object> obj, double timeout); |
|
|
Socket (Handle<Object> obj, double timeout); |
|
|
~Socket (); |
|
|
~Socket (); |
|
|
|
|
|
|
|
|
int ConnectTCP (char *port, char *host); |
|
|
|
|
|
void Write (Handle<Value> arg); |
|
|
|
|
|
void Disconnect (); |
|
|
|
|
|
|
|
|
|
|
|
void SetEncoding (enum encoding); |
|
|
void SetEncoding (enum encoding); |
|
|
void SetTimeout (double); |
|
|
void SetTimeout (double); |
|
|
|
|
|
|
|
|
void OnConnect (); |
|
|
static Handle<Value> New (const Arguments& args); |
|
|
void OnRead (const void *buf, size_t count); |
|
|
static Handle<Value> Write (const Arguments& args); |
|
|
void OnDrain (); |
|
|
static Handle<Value> Close (const Arguments& args); |
|
|
void OnError (oi_error e); |
|
|
static Handle<Value> ConnectTCP (const Arguments& args); |
|
|
void OnClose (); |
|
|
|
|
|
|
|
|
static void OnConnect (oi_socket *socket); |
|
|
|
|
|
static void OnRead (oi_socket *s, const void *buf, size_t count); |
|
|
|
|
|
static void OnDrain (oi_socket *s); |
|
|
|
|
|
static void OnError (oi_socket *s, oi_error e); |
|
|
|
|
|
static void OnClose (oi_socket *s); |
|
|
|
|
|
static void OnTimeout (oi_socket *s); |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
|
|
|
static Socket* Unwrap (Handle<Object> handle); |
|
|
|
|
|
static void MakeWeak (Persistent<Value> _, void *data); |
|
|
|
|
|
enum {UTF8, RAW} encoding_; |
|
|
oi_socket socket_; |
|
|
oi_socket socket_; |
|
|
struct addrinfo *address_; |
|
|
struct addrinfo *address_; |
|
|
Persistent<Object> js_object_; |
|
|
Persistent<Object> handle_; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
static void |
|
|
Handle<Value> |
|
|
on_connect (oi_socket *socket) |
|
|
Socket::New(const Arguments& args) |
|
|
{ |
|
|
|
|
|
Socket *s = static_cast<Socket*> (socket->data); |
|
|
|
|
|
s->OnConnect(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
on_read (oi_socket *socket, const void *buf, size_t count) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *s = static_cast<Socket*> (socket->data); |
|
|
|
|
|
s->OnRead(buf, count); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
on_drain (oi_socket *socket) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *s = static_cast<Socket*> (socket->data); |
|
|
|
|
|
s->OnDrain(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
on_error (oi_socket *socket, oi_error e) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *s = static_cast<Socket*> (socket->data); |
|
|
|
|
|
s->OnError(e); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
on_timeout (oi_socket *socket) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *s = static_cast<Socket*> (socket->data); |
|
|
|
|
|
s->OnTimeout(e); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
|
on_close (oi_socket *socket) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *s = static_cast<Socket*> (socket->data); |
|
|
|
|
|
s->OnClose(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Handle<Value> |
|
|
|
|
|
NewSocket (const Arguments& args) |
|
|
|
|
|
{ |
|
|
{ |
|
|
if (args.Length() > 1) |
|
|
if (args.Length() > 1) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
@ -97,7 +63,7 @@ NewSocket (const Arguments& args) |
|
|
|
|
|
|
|
|
// Default options
|
|
|
// Default options
|
|
|
double timeout = 60.0; // in seconds
|
|
|
double timeout = 60.0; // in seconds
|
|
|
enum {RAW, UTF8} encoding = RAW; |
|
|
enum {UTF8, RAW} encoding ; |
|
|
|
|
|
|
|
|
// Set options from argument.
|
|
|
// Set options from argument.
|
|
|
if (args.Length() == 1 && args[0]->IsObject()) { |
|
|
if (args.Length() == 1 && args[0]->IsObject()) { |
|
@ -120,30 +86,30 @@ NewSocket (const Arguments& args) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Socket *s = new Socket(args.This(), timeout); |
|
|
Socket *s = new Socket(args.Holder(), timeout); |
|
|
if(s == NULL) |
|
|
if(s == NULL) |
|
|
return Undefined(); // XXX raise error?
|
|
|
return Undefined(); // XXX raise error?
|
|
|
|
|
|
|
|
|
return args.This(); |
|
|
return args.This(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static Socket* |
|
|
Socket* |
|
|
Unwrapsocket (Handle<Object> obj) |
|
|
Socket::Unwrap (Handle<Object> handle) |
|
|
{ |
|
|
{ |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0)); |
|
|
Handle<External> field = Handle<External>::Cast(handle->GetInternalField(0)); |
|
|
Socket* socket = static_cast<Socket*>(field->Value()); |
|
|
Socket* socket = static_cast<Socket*>(field->Value()); |
|
|
return socket; |
|
|
return socket; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static Handle<Value> |
|
|
Handle<Value> |
|
|
SocketConnectTCPCallback (const Arguments& args) |
|
|
Socket::ConnectTCP (const Arguments& args) |
|
|
{ |
|
|
{ |
|
|
if (args.Length() < 1) |
|
|
if (args.Length() < 1) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
Socket *socket = Unwrapsocket(args.Holder()); |
|
|
Socket *socket = Socket::Unwrap(args.Holder()); |
|
|
|
|
|
|
|
|
String::AsciiValue port(args[0]); |
|
|
String::AsciiValue port(args[0]); |
|
|
|
|
|
|
|
@ -153,171 +119,137 @@ SocketConnectTCPCallback (const Arguments& args) |
|
|
host = *host_v; |
|
|
host = *host_v; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int r = socket->ConnectTCP(*port, host); |
|
|
int r; |
|
|
// TODO raise error if r != 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* FIXME Blocking DNS resolution. */ |
|
|
|
|
|
printf("resolving host: %s, port: %s\n", host, *port); |
|
|
|
|
|
r = getaddrinfo (host, *port, &tcp_hints, &socket->address_); |
|
|
|
|
|
if(r != 0) { |
|
|
|
|
|
perror("getaddrinfo"); |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static Handle<Value> |
|
|
r = oi_socket_connect (&socket->socket_, socket->address_); |
|
|
SocketWriteCallback (const Arguments& args) |
|
|
if(r != 0) { |
|
|
{ |
|
|
perror("oi_socket_connect"); |
|
|
HandleScope scope; |
|
|
|
|
|
Socket *socket = Unwrapsocket(args.Holder()); |
|
|
|
|
|
socket->Write(args[0]); |
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
oi_socket_attach (&socket->socket_, node_loop()); |
|
|
|
|
|
|
|
|
|
|
|
freeaddrinfo(socket->address_); |
|
|
|
|
|
socket->address_ = NULL; |
|
|
|
|
|
// TODO raise error if r != 0
|
|
|
|
|
|
|
|
|
static Handle<Value> |
|
|
return Undefined(); |
|
|
SocketCloseCallback (const Arguments& args) |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> |
|
|
|
|
|
Socket::Close (const Arguments& args) |
|
|
{ |
|
|
{ |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
Socket *socket = Unwrapsocket(args.Holder()); |
|
|
Socket *socket = Socket::Unwrap(args.Holder()); |
|
|
socket->Disconnect(); |
|
|
oi_socket_close(&socket->socket_); |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
void |
|
|
DestroySocket (Persistent<Value> _, void *data) |
|
|
Socket::MakeWeak (Persistent<Value> _, void *data) |
|
|
{ |
|
|
{ |
|
|
Socket *s = static_cast<Socket*> (data); |
|
|
Socket *s = static_cast<Socket*> (data); |
|
|
delete s; |
|
|
delete s; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Socket::Socket(Handle<Object> js_object, double timeout) |
|
|
Socket::Socket(Handle<Object> handle, double timeout) |
|
|
{ |
|
|
{ |
|
|
oi_socket_init(&socket_, timeout); |
|
|
oi_socket_init(&socket_, timeout); |
|
|
socket_.on_connect = on_connect; |
|
|
socket_.on_connect = Socket::OnConnect; |
|
|
socket_.on_read = on_read; |
|
|
socket_.on_read = Socket::OnRead; |
|
|
socket_.on_drain = on_drain; |
|
|
socket_.on_drain = Socket::OnDrain; |
|
|
socket_.on_error = on_error; |
|
|
socket_.on_error = Socket::OnError; |
|
|
socket_.on_close = on_close; |
|
|
socket_.on_close = Socket::OnClose; |
|
|
socket_.on_timeout = on_timeout; |
|
|
socket_.on_timeout = Socket::OnTimeout; |
|
|
socket_.data = this; |
|
|
socket_.data = this; |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
js_object_ = Persistent<Object>::New(js_object); |
|
|
handle_ = Persistent<Object>::New(handle); |
|
|
js_object_->SetInternalField (0, External::New(this)); |
|
|
handle_->SetInternalField (0, External::New(this)); |
|
|
js_object_.MakeWeak (this, DestroySocket); |
|
|
handle_.MakeWeak (this, Socket::MakeWeak); |
|
|
|
|
|
|
|
|
|
|
|
encoding_ = UTF8; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Socket::~Socket () |
|
|
Socket::~Socket () |
|
|
{ |
|
|
{ |
|
|
Disconnect(); |
|
|
oi_socket_close(&socket_); |
|
|
oi_socket_detach(&socket_); |
|
|
oi_socket_detach(&socket_); |
|
|
js_object_.Dispose(); |
|
|
handle_.Dispose(); |
|
|
js_object_.Clear(); // necessary?
|
|
|
handle_.Clear(); // necessary?
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static struct addrinfo tcp_hints = |
|
|
Handle<Value> |
|
|
/* ai_flags */ { AI_PASSIVE |
|
|
Socket::Write (const Arguments& args) |
|
|
/* ai_family */ , AF_UNSPEC |
|
|
|
|
|
/* ai_socktype */ , SOCK_STREAM |
|
|
|
|
|
/* ai_protocol */ , 0 |
|
|
|
|
|
/* ai_addrlen */ , 0 |
|
|
|
|
|
/* ai_addr */ , 0 |
|
|
|
|
|
/* ai_canonname */ , 0 |
|
|
|
|
|
/* ai_next */ , 0 |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
Socket::ConnectTCP(char *port, char *host) |
|
|
|
|
|
{ |
|
|
{ |
|
|
int r; |
|
|
|
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
js_object_->Set(readyState_str, readyStateCONNECTING); |
|
|
Socket *socket = Socket::Unwrap(args.Holder()); |
|
|
|
|
|
|
|
|
/* FIXME Blocking DNS resolution. */ |
|
|
if (args[0] == Null()) { |
|
|
printf("resolving host: %s, port: %s\n", host, port); |
|
|
oi_socket_write_eof(&socket->socket_); |
|
|
r = getaddrinfo (host, port, &tcp_hints, &address); |
|
|
|
|
|
if(r != 0) { |
|
|
|
|
|
perror("getaddrinfo"); |
|
|
|
|
|
return r; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
r = oi_socket_connect (&socket, address); |
|
|
} else if (args[0]->IsString()) { |
|
|
if(r != 0) { |
|
|
// utf8 encoding
|
|
|
perror("oi_socket_connect"); |
|
|
Local<String> s = args[0]->ToString(); |
|
|
return r; |
|
|
size_t length = s->Utf8Length(); |
|
|
} |
|
|
oi_buf *buf = oi_buf_new2(length); |
|
|
oi_socket_attach (&socket, node_loop()); |
|
|
s->WriteUtf8(buf->base, length); |
|
|
|
|
|
oi_socket_write(&socket->socket_, buf); |
|
|
freeaddrinfo(address); |
|
|
|
|
|
address = NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Socket::Write (Handle<Value> arg) |
|
|
|
|
|
{ |
|
|
|
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
|
|
|
if (arg == Null()) { |
|
|
|
|
|
|
|
|
|
|
|
oi_socket_write_eof(&socket); |
|
|
|
|
|
|
|
|
|
|
|
} else if (arg->IsString()) { |
|
|
|
|
|
Local<String> s = arg->ToString(); |
|
|
|
|
|
|
|
|
|
|
|
size_t l1 = s->Utf8Length(), l2; |
|
|
|
|
|
oi_buf *buf = oi_buf_new2(l1); |
|
|
|
|
|
l2 = s->WriteUtf8(buf->base, l1); |
|
|
|
|
|
assert(l1 == l2); |
|
|
|
|
|
|
|
|
|
|
|
oi_socket_write(&socket, buf); |
|
|
|
|
|
|
|
|
|
|
|
} else if (arg->IsArray()) { |
|
|
} else if (args[0]->IsArray()) { |
|
|
|
|
|
// raw encoding
|
|
|
|
|
|
Handle<Array> array = Handle<Array>::Cast(args[0]); |
|
|
size_t length = array->Length(); |
|
|
size_t length = array->Length(); |
|
|
Handle<Array> array = Handle<Array>::Cast(arg); |
|
|
|
|
|
oi_buf *buf = oi_buf_new2(length); |
|
|
oi_buf *buf = oi_buf_new2(length); |
|
|
for (int i = 0; i < length; i++) { |
|
|
for (int i = 0; i < length; i++) { |
|
|
Local<Value> int_value = array->Get(Integer::New(i)); |
|
|
Local<Value> int_value = array->Get(Integer::New(i)); |
|
|
buf[i] = int_value->Int32Value(); |
|
|
buf->base[i] = int_value->Int32Value(); |
|
|
} |
|
|
} |
|
|
|
|
|
oi_socket_write(&socket->socket_, buf); |
|
|
oi_socket_write(&socket, buf); |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// raise error bad argument.
|
|
|
// raise error bad argument.
|
|
|
assert(0); |
|
|
assert(0); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
return Undefined(); |
|
|
Socket::Disconnect() |
|
|
|
|
|
{ |
|
|
|
|
|
oi_socket_close(&socket); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
Socket::OnConnect() |
|
|
Socket::OnConnect (oi_socket *s) |
|
|
{ |
|
|
{ |
|
|
HandleScope scope; |
|
|
Socket *socket = static_cast<Socket*> (s->data); |
|
|
|
|
|
|
|
|
assert(READY_STATE_CONNECTING == ReadyState()); |
|
|
HandleScope scope; |
|
|
js_object_->Set(readyState_str, readyStateOPEN); |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> on_connect_value = js_object_->Get( String::NewSymbol("on_connect") ); |
|
|
Handle<Value> on_connect_value = socket->handle_->Get( String::NewSymbol("onConnect") ); |
|
|
if (!on_connect_value->IsFunction()) |
|
|
if (!on_connect_value->IsFunction()) |
|
|
return; |
|
|
return; |
|
|
Handle<Function> on_connect = Handle<Function>::Cast(on_connect_value); |
|
|
Handle<Function> on_connect = Handle<Function>::Cast(on_connect_value); |
|
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
TryCatch try_catch; |
|
|
|
|
|
|
|
|
Handle<Value> r = on_connect->Call(js_object_, 0, NULL); |
|
|
Handle<Value> r = on_connect->Call(socket->handle_, 0, NULL); |
|
|
|
|
|
|
|
|
if(try_catch.HasCaught()) |
|
|
if(try_catch.HasCaught()) |
|
|
node_fatal_exception(try_catch); |
|
|
node_fatal_exception(try_catch); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
Socket::OnRead (const void *buf, size_t count) |
|
|
Socket::OnRead (oi_socket *s, const void *buf, size_t count) |
|
|
{ |
|
|
{ |
|
|
|
|
|
Socket *socket = static_cast<Socket*> (s->data); |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
assert(READY_STATE_OPEN == ReadyState()); |
|
|
Handle<Value> onread_value = socket->handle_->Get( String::NewSymbol("onRead") ); |
|
|
|
|
|
|
|
|
Handle<Value> onread_value = js_object_->Get( String::NewSymbol("on_read") ); |
|
|
|
|
|
if (!onread_value->IsFunction()) return; |
|
|
if (!onread_value->IsFunction()) return; |
|
|
Handle<Function> onread = Handle<Function>::Cast(onread_value); |
|
|
Handle<Function> onread = Handle<Function>::Cast(onread_value); |
|
|
|
|
|
|
|
@ -325,101 +257,118 @@ Socket::OnRead (const void *buf, size_t count) |
|
|
Handle<Value> argv[argc]; |
|
|
Handle<Value> argv[argc]; |
|
|
|
|
|
|
|
|
if(count) { |
|
|
if(count) { |
|
|
Handle<String> chunk = String::New((const char*)buf, count); // TODO binary data?
|
|
|
if(socket->encoding_ == UTF8) { |
|
|
|
|
|
// utf8 encoding
|
|
|
|
|
|
Handle<String> chunk = String::New((const char*)buf, count); |
|
|
argv[0] = chunk; |
|
|
argv[0] = chunk; |
|
|
} else { |
|
|
} else { |
|
|
// TODO eof? delete write method?
|
|
|
// raw encoding
|
|
|
argv[0] = Null(); |
|
|
Local<Array> array = Array::New(count); |
|
|
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
|
|
int val = static_cast<const int*>(buf)[i]; |
|
|
|
|
|
array->Set(Integer::New(i), Integer::New(val)); |
|
|
|
|
|
} |
|
|
|
|
|
argv[0] = array; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
argv[0] = Local<Value>::New(Null()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
TryCatch try_catch; |
|
|
|
|
|
|
|
|
Handle<Value> r = onread->Call(js_object_, argc, argv); |
|
|
Handle<Value> r = onread->Call(socket->handle_, argc, argv); |
|
|
|
|
|
|
|
|
if(try_catch.HasCaught()) |
|
|
if(try_catch.HasCaught()) |
|
|
node_fatal_exception(try_catch); |
|
|
node_fatal_exception(try_catch); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
Socket::OnClose () |
|
|
Socket::OnClose (oi_socket *s) |
|
|
{ |
|
|
{ |
|
|
|
|
|
Socket *socket = static_cast<Socket*> (s->data); |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
printf("onclose readyState %d\n", ReadyState()); |
|
|
Handle<Value> onclose_value = socket->handle_->Get( String::NewSymbol("onClose") ); |
|
|
|
|
|
if (!onclose_value->IsFunction()) return; |
|
|
|
|
|
Handle<Function> onclose = Handle<Function>::Cast(onclose_value); |
|
|
|
|
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
|
|
|
|
|
|
assert(READY_STATE_OPEN == ReadyState()); |
|
|
Handle<Value> r = onclose->Call(socket->handle_, 0, NULL); |
|
|
js_object_->Set(readyState_str, readyStateCLOSED); |
|
|
|
|
|
|
|
|
if(try_catch.HasCaught()) |
|
|
|
|
|
node_fatal_exception(try_catch); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
Socket::OnDrain (oi_socket *s) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *socket = static_cast<Socket*> (s->data); |
|
|
|
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
Handle<Value> onclose_value = js_object_->Get( String::NewSymbol("on_close") ); |
|
|
Handle<Value> onclose_value = socket->handle_->Get( String::NewSymbol("onDrain") ); |
|
|
if (!onclose_value->IsFunction()) return; |
|
|
if (!onclose_value->IsFunction()) return; |
|
|
Handle<Function> onclose = Handle<Function>::Cast(onclose_value); |
|
|
Handle<Function> onclose = Handle<Function>::Cast(onclose_value); |
|
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
TryCatch try_catch; |
|
|
|
|
|
|
|
|
Handle<Value> r = onclose->Call(js_object_, 0, NULL); |
|
|
Handle<Value> r = onclose->Call(socket->handle_, 0, NULL); |
|
|
|
|
|
|
|
|
if(try_catch.HasCaught()) |
|
|
if(try_catch.HasCaught()) |
|
|
node_fatal_exception(try_catch); |
|
|
node_fatal_exception(try_catch); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
Socket::OnError (oi_socket *s, oi_error e) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *socket = static_cast<Socket*> (s->data); |
|
|
|
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> onclose_value = socket->handle_->Get( String::NewSymbol("onError") ); |
|
|
|
|
|
if (!onclose_value->IsFunction()) return; |
|
|
|
|
|
Handle<Function> onclose = Handle<Function>::Cast(onclose_value); |
|
|
|
|
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> r = onclose->Call(socket->handle_, 0, NULL); |
|
|
|
|
|
|
|
|
|
|
|
if(try_catch.HasCaught()) |
|
|
|
|
|
node_fatal_exception(try_catch); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
Socket::OnTimeout (oi_socket *s) |
|
|
|
|
|
{ |
|
|
|
|
|
Socket *socket = static_cast<Socket*> (s->data); |
|
|
|
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> onclose_value = socket->handle_->Get( String::NewSymbol("onTimeout") ); |
|
|
|
|
|
if (!onclose_value->IsFunction()) return; |
|
|
|
|
|
Handle<Function> onclose = Handle<Function>::Cast(onclose_value); |
|
|
|
|
|
|
|
|
|
|
|
TryCatch try_catch; |
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> r = onclose->Call(socket->handle_, 0, NULL); |
|
|
|
|
|
|
|
|
|
|
|
if(try_catch.HasCaught()) |
|
|
|
|
|
node_fatal_exception(try_catch); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
NodeInit_net (Handle<Object> target) |
|
|
NodeInit_net (Handle<Object> target) |
|
|
{ |
|
|
{ |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
//
|
|
|
Local<FunctionTemplate> socket_template = FunctionTemplate::New(Socket::New); |
|
|
// Socket
|
|
|
|
|
|
//
|
|
|
|
|
|
Local<FunctionTemplate> socket_template = FunctionTemplate::New(NewSocket); |
|
|
|
|
|
target->Set(String::NewSymbol("Socket"), socket_template->GetFunction()); |
|
|
|
|
|
socket_template->InstanceTemplate()->SetInternalFieldCount(1); |
|
|
socket_template->InstanceTemplate()->SetInternalFieldCount(1); |
|
|
|
|
|
target->Set(String::NewSymbol("Socket"), socket_template->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
NODE_SET_METHOD(socket_template->InstanceTemplate(), "connectTCP", Socket::ConnectTCP); |
|
|
|
|
|
//NODE_SET_METHOD(socket_template->InstanceTemplate(), "connectUNIX", Socket::ConnectUNIX);
|
|
|
|
|
|
NODE_SET_METHOD(socket_template->InstanceTemplate(), "write", Socket::Write); |
|
|
|
|
|
NODE_SET_METHOD(socket_template->InstanceTemplate(), "close", Socket::Close); |
|
|
|
|
|
|
|
|
// socket.connectTCP()
|
|
|
|
|
|
Local<FunctionTemplate> socket_connect_tcp = |
|
|
|
|
|
FunctionTemplate::New(SocketConnectTCPCallback); |
|
|
|
|
|
socket_template->InstanceTemplate()->Set(String::NewSymbol("connectTCP"), |
|
|
|
|
|
socket_connect_tcp->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
// socket.connectUNIX()
|
|
|
|
|
|
Local<FunctionTemplate> socket_connect_unix = |
|
|
|
|
|
FunctionTemplate::New(SocketConnectUNIXCallback); |
|
|
|
|
|
socket_template->InstanceTemplate()->Set(String::NewSymbol("connectUNIX"), |
|
|
|
|
|
socket_connect_unix->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
// socket.write()
|
|
|
|
|
|
Local<FunctionTemplate> socket_write = |
|
|
|
|
|
FunctionTemplate::New(SocketWriteCallback); |
|
|
|
|
|
socket_template->InstanceTemplate()->Set(String::NewSymbol("write"), |
|
|
|
|
|
socket_write->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
// socket.close()
|
|
|
|
|
|
Local<FunctionTemplate> socket_close = |
|
|
|
|
|
FunctionTemplate::New(SocketCloseCallback); |
|
|
|
|
|
socket_template->InstanceTemplate()->Set(String::NewSymbol("close"), |
|
|
|
|
|
socket_close->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// Server
|
|
|
|
|
|
//
|
|
|
|
|
|
Local<FunctionTemplate> server_template = FunctionTemplate::New(NewServer); |
|
|
|
|
|
target->Set(String::NewSymbol("Server"), server_template->GetFunction()); |
|
|
|
|
|
server_template->InstanceTemplate()->SetInternalFieldCount(1); |
|
|
|
|
|
|
|
|
|
|
|
// server.listenTCP()
|
|
|
|
|
|
Local<FunctionTemplate> server_listenTCP = |
|
|
|
|
|
FunctionTemplate::New(ServerListenTCPCallback); |
|
|
|
|
|
server_template->InstanceTemplate()->Set(String::NewSymbol("listenTCP"), |
|
|
|
|
|
server_listenTCP->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
// server.listenUNIX()
|
|
|
|
|
|
Local<FunctionTemplate> server_listenUNIX = |
|
|
|
|
|
FunctionTemplate::New(ServerListenUNIXCallback); |
|
|
|
|
|
server_template->InstanceTemplate()->Set(String::NewSymbol("listenUNIX"), |
|
|
|
|
|
server_listenTCP->GetFunction()); |
|
|
|
|
|
|
|
|
|
|
|
// server.close()
|
|
|
|
|
|
Local<FunctionTemplate> server_close = FunctionTemplate::New(ServerCloseCallback); |
|
|
|
|
|
server_template->InstanceTemplate()->Set(String::NewSymbol("close"), |
|
|
|
|
|
server_close->GetFunction()); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|