Browse Source

complete tcp client (for the most part)

v0.7.4-release
Ryan 16 years ago
parent
commit
e2d20fe293
  1. 82
      node_tcp.cc

82
node_tcp.cc

@ -4,6 +4,7 @@
#include <oi_socket.h> #include <oi_socket.h>
#include <oi_buf.h> #include <oi_buf.h>
#include <assert.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
@ -31,6 +32,8 @@ public:
void Disconnect(); void Disconnect();
void OnOpen(); void OnOpen();
void OnRead(const void *buf, size_t count);
void OnClose();
private: private:
oi_socket socket; oi_socket socket;
@ -39,14 +42,27 @@ private:
}; };
static void on_connect static void
( oi_socket *socket on_connect (oi_socket *socket)
)
{ {
TCPClient *client = static_cast<TCPClient*> (socket->data); TCPClient *client = static_cast<TCPClient*> (socket->data);
client->OnOpen(); client->OnOpen();
} }
static void
on_close (oi_socket *socket)
{
TCPClient *client = static_cast<TCPClient*> (socket->data);
client->OnClose();
}
static void
on_read (oi_socket *socket, const void *buf, size_t count)
{
TCPClient *client = static_cast<TCPClient*> (socket->data);
client->OnRead(buf, count);
}
static struct addrinfo tcp_hints = static struct addrinfo tcp_hints =
/* ai_flags */ { AI_PASSIVE /* ai_flags */ { AI_PASSIVE
/* ai_family */ , AF_UNSPEC /* ai_family */ , AF_UNSPEC
@ -120,11 +136,11 @@ TCPClient::TCPClient(Handle<Object> _js_client)
{ {
oi_socket_init(&socket, 30.0); // TODO adjustable timeout oi_socket_init(&socket, 30.0); // TODO adjustable timeout
socket.on_connect = on_connect; socket.on_connect = on_connect;
socket.on_read = NULL; socket.on_read = on_read;
socket.on_drain = NULL; socket.on_drain = NULL;
socket.on_error = NULL; socket.on_error = NULL;
socket.on_close = NULL; socket.on_close = on_close;
socket.on_timeout = NULL; socket.on_timeout = on_close;
socket.data = this; socket.data = this;
HandleScope scope; HandleScope scope;
@ -193,10 +209,12 @@ TCPClient::Disconnect()
oi_socket_close(&socket); oi_socket_close(&socket);
} }
void TCPClient::OnOpen() void
TCPClient::OnOpen()
{ {
HandleScope scope; HandleScope scope;
assert(READY_STATE_CONNECTING == js_client->Get(readyState_str)->IntegerValue());
js_client->Set(readyState_str, readyState_OPEN); js_client->Set(readyState_str, readyState_OPEN);
Handle<Value> onopen_value = js_client->Get( String::NewSymbol("onopen") ); Handle<Value> onopen_value = js_client->Get( String::NewSymbol("onopen") );
@ -212,6 +230,56 @@ void TCPClient::OnOpen()
node_fatal_exception(try_catch); node_fatal_exception(try_catch);
} }
void
TCPClient::OnRead(const void *buf, size_t count)
{
HandleScope scope;
assert(READY_STATE_OPEN == js_client->Get(readyState_str)->IntegerValue());
Handle<Value> onread_value = js_client->Get( String::NewSymbol("onread") );
if (!onread_value->IsFunction()) return;
Handle<Function> onread = Handle<Function>::Cast(onread_value);
const int argc = 1;
Handle<Value> argv[argc];
if(count) {
Handle<String> chunk = String::New((const char*)buf, count); // TODO binary data?
argv[0] = chunk;
} else {
// TODO eof? delete write method?
argv[0] = Null();
}
TryCatch try_catch;
Handle<Value> r = onread->Call(js_client, argc, argv);
if(try_catch.HasCaught())
node_fatal_exception(try_catch);
}
void
TCPClient::OnClose()
{
HandleScope scope;
assert(READY_STATE_OPEN == js_client->Get(readyState_str)->IntegerValue());
js_client->Set(readyState_str, readyState_CLOSED);
Handle<Value> onclose_value = js_client->Get( String::NewSymbol("onclose") );
if (!onclose_value->IsFunction()) return;
Handle<Function> onclose = Handle<Function>::Cast(onclose_value);
TryCatch try_catch;
Handle<Value> r = onclose->Call(js_client, 0, NULL);
if(try_catch.HasCaught())
node_fatal_exception(try_catch);
}
void void
Init_tcp (Handle<Object> target) Init_tcp (Handle<Object> target)
{ {

Loading…
Cancel
Save