From 5f902a61e1af296afec9af785856dd116bb1a570 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 22 Apr 2009 13:52:30 +0200 Subject: [PATCH] tcp server is accepting connections now. (experiencing a problem with writing rawEncoding on the sockets. will fix in next commit.) --- src/net.cc | 81 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/src/net.cc b/src/net.cc index 97bfb3f73ee..bb10537c1d2 100644 --- a/src/net.cc +++ b/src/net.cc @@ -15,6 +15,8 @@ using namespace v8; +static Persistent socket_template; + #define ON_CONNECT_SYMBOL String::NewSymbol("onConnect") #define ON_READ_SYMBOL String::NewSymbol("onRead") @@ -80,6 +82,8 @@ private: char *host_; char *port_; + + friend class Server; }; Server::Server (Handle handle, int backlog) @@ -106,25 +110,86 @@ Server::~Server () Handle Server::New (const Arguments& args) { - ; + HandleScope scope; + + int backlog = 1024; // default + if (args.Length() > 0 && args[0]->IsNumber()) + backlog = args[0]->IntegerValue(); + + Server *server = new Server(args.Holder(), backlog); + if(server == NULL) + return Undefined(); // XXX raise error? + + return args.This(); } Handle Server::ListenTCP (const Arguments& args) { - ; + if (args.Length() < 2) return Undefined(); + HandleScope scope; + + Server *server = Server::Unwrap(args.Holder()); + + String::AsciiValue port(args[0]); + + int callback_index = 1; + char *host = NULL; + if (args[1]->IsString()) { + callback_index = 2; + String::AsciiValue host_v(args[1]->ToString()); + if(args[1]->IsString()) host = *host_v; + } + + // For servers call getaddrinfo inline. This is blocking but it shouldn't + // matter--ever. If someone actually complains then simply swap it out + // with a libeio call. + struct addrinfo *address = NULL; + int r = getaddrinfo(host, *port, &tcp_hints, &address); + if (r != 0) + return ThrowException(String::New("Error looking up hostname")); + + if (!args[callback_index]->IsFunction()) + return ThrowException(String::New("Must supply onConnection callback")); + + server->handle_->Set(String::NewSymbol("onConnection"), args[callback_index]); + + r = oi_server_listen(&server->server_, address); + if (r != 0) + return ThrowException(String::New("Error listening on port")); + oi_server_attach(&server->server_, node_loop()); + + freeaddrinfo(address); + + return Undefined(); } Handle Server::Close (const Arguments& args) { - ; + } oi_socket* -Server::OnConnection (oi_server *, struct sockaddr *remote_addr, socklen_t remote_addr_len) +Server::OnConnection (oi_server *s, struct sockaddr *remote_addr, socklen_t remote_addr_len) { - ; + Server *server = static_cast (s->data); + HandleScope scope; + + Socket *socket = new Socket(socket_template->GetFunction()->NewInstance(), 60.0); + socket->handle_->Delete(String::NewSymbol("connectTCP")); + + Local callback_v = server->handle_->Get(String::NewSymbol("onConnection")); + if (!callback_v->IsFunction()) + return NULL; // produce error? + + Local callback = Local::Cast(callback_v); + const int argc = 1; + Local argv[argc]; + argv[0] = Local::New(socket->handle_); + callback->Call(server->handle_, argc, argv); + + return &socket->socket_; } Server* @@ -220,7 +285,7 @@ Socket::ConnectTCP (const Arguments& args) String::AsciiValue port(args[0]); socket->port_ = strdup(*port); - char *host = NULL; + assert(socket->host_ == NULL); String::AsciiValue host_v(args[1]->ToString()); if(args[1]->IsString()) { socket->host_ = strdup(*host_v); @@ -524,13 +589,13 @@ Socket::OnTimeout (oi_socket *s) node_fatal_exception(try_catch); } - void NodeInit_net (Handle target) { HandleScope scope; - Local socket_template = FunctionTemplate::New(Socket::New); + Local socket_template_local = FunctionTemplate::New(Socket::New); + socket_template = Persistent::New(socket_template_local); socket_template->InstanceTemplate()->SetInternalFieldCount(1); target->Set(String::NewSymbol("Socket"), socket_template->GetFunction());