Browse Source

add Connection::SendEOF. modify test accordingly.

v0.7.4-release
Ryan 16 years ago
parent
commit
1713386580
  1. 33
      src/net.cc
  2. 17
      src/net.h
  3. 45
      test/test-pingpong.js

33
src/net.cc

@ -19,6 +19,7 @@ using namespace node;
#define ON_DRAIN_SYMBOL String::NewSymbol("onDrain") #define ON_DRAIN_SYMBOL String::NewSymbol("onDrain")
#define ON_TIMEOUT_SYMBOL String::NewSymbol("onTimeout") #define ON_TIMEOUT_SYMBOL String::NewSymbol("onTimeout")
#define ON_ERROR_SYMBOL String::NewSymbol("onError") #define ON_ERROR_SYMBOL String::NewSymbol("onError")
#define ON_EOF_SYMBOL String::NewSymbol("onEOF")
#define SEND_SYMBOL String::NewSymbol("send") #define SEND_SYMBOL String::NewSymbol("send")
#define DISCONNECT_SYMBOL String::NewSymbol("disconnect") #define DISCONNECT_SYMBOL String::NewSymbol("disconnect")
@ -55,14 +56,15 @@ Connection::Initialize (v8::Handle<v8::Object> target)
NODE_SET_METHOD(t->InstanceTemplate(), "connect", Connection::v8Connect); NODE_SET_METHOD(t->InstanceTemplate(), "connect", Connection::v8Connect);
NODE_SET_METHOD(t->InstanceTemplate(), "disconnect", Connection::v8Disconnect); NODE_SET_METHOD(t->InstanceTemplate(), "disconnect", Connection::v8Disconnect);
NODE_SET_METHOD(t->InstanceTemplate(), "send", Connection::v8Send); NODE_SET_METHOD(t->InstanceTemplate(), "send", Connection::v8Send);
NODE_SET_METHOD(t->InstanceTemplate(), "sendEOF", Connection::v8SendEOF);
} }
Local<Object> Local<Object>
Connection::NewInstance (Local<Function> protocol) Connection::NewServerSideInstance (Local<Function> protocol, Handle<Object> server)
{ {
HandleScope scope; HandleScope scope;
Handle<Value> argv[] = { protocol }; Handle<Value> argv[] = { protocol, server };
Local<Object> instance = tcp_connection_constructor->NewInstance(1, argv); Local<Object> instance = tcp_connection_constructor->NewInstance(2, argv);
return scope.Close(instance); return scope.Close(instance);
} }
@ -124,8 +126,16 @@ Connection::v8New (const Arguments& args)
return ThrowException(String::New("Must pass a class as the first argument.")); return ThrowException(String::New("Must pass a class as the first argument."));
Handle<Function> protocol = Handle<Function>::Cast(args[0]); Handle<Function> protocol = Handle<Function>::Cast(args[0]);
Handle<Value> argv[] = { args.This() };
Local<Object> protocol_instance = protocol->NewInstance(1, argv); int argc = args.Length();
Handle<Value> argv[argc];
argv[0] = args.This();
for (int i = 1; i < args.Length(); i++) {
argv[i] = args[i];
}
Local<Object> protocol_instance = protocol->NewInstance(argc, argv);
args.This()->Set(PROTOCOL_SYMBOL, protocol_instance); args.This()->Set(PROTOCOL_SYMBOL, protocol_instance);
new Connection(args.This()); new Connection(args.This());
@ -252,6 +262,15 @@ Connection::v8Send (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value>
Connection::v8SendEOF (const Arguments& args)
{
HandleScope scope;
Connection *connection = NODE_UNWRAP(Connection, args.Holder());
connection->SendEOF();
return Undefined();
}
void void
Connection::OnReceive (const void *buf, size_t len) Connection::OnReceive (const void *buf, size_t len)
{ {
@ -312,6 +331,7 @@ DEFINE_SIMPLE_CALLBACK(Connection::OnConnect, ON_CONNECT_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnDrain, ON_DRAIN_SYMBOL) DEFINE_SIMPLE_CALLBACK(Connection::OnDrain, ON_DRAIN_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnDisconnect, ON_DISCONNECT_SYMBOL) DEFINE_SIMPLE_CALLBACK(Connection::OnDisconnect, ON_DISCONNECT_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnTimeout, ON_TIMEOUT_SYMBOL) DEFINE_SIMPLE_CALLBACK(Connection::OnTimeout, ON_TIMEOUT_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnEOF, ON_EOF_SYMBOL)
void void
Acceptor::Initialize (Handle<Object> target) Acceptor::Initialize (Handle<Object> target)
@ -367,7 +387,8 @@ Acceptor::OnConnection (struct sockaddr *addr, socklen_t len)
} }
Local<Function> protocol = Local<Function>::Cast(protocol_v); Local<Function> protocol = Local<Function>::Cast(protocol_v);
Local<Object> connection_handle = Connection::NewInstance(protocol); Local<Object> connection_handle =
Connection::NewServerSideInstance(protocol, handle_);
Connection *connection = new Connection(connection_handle); Connection *connection = new Connection(connection_handle);
return connection; return connection;

17
src/net.h

@ -24,7 +24,11 @@ public:
oi_socket_write (&socket_, buf); oi_socket_write (&socket_, buf);
} }
void Disconnect () { void SendEOF (void) {
oi_socket_write_eof (&socket_);
}
void Disconnect (void) {
oi_socket_close (&socket_); oi_socket_close (&socket_);
} }
@ -32,17 +36,21 @@ protected:
static v8::Handle<v8::Value> v8New (const v8::Arguments& args); static v8::Handle<v8::Value> v8New (const v8::Arguments& args);
static v8::Handle<v8::Value> v8Connect (const v8::Arguments& args); static v8::Handle<v8::Value> v8Connect (const v8::Arguments& args);
static v8::Handle<v8::Value> v8Send (const v8::Arguments& args); static v8::Handle<v8::Value> v8Send (const v8::Arguments& args);
static v8::Handle<v8::Value> v8SendEOF (const v8::Arguments& args);
static v8::Handle<v8::Value> v8Disconnect (const v8::Arguments& args); static v8::Handle<v8::Value> v8Disconnect (const v8::Arguments& args);
void OnConnect (void); void OnConnect (void);
void OnReceive (const void *buf, size_t len); void OnReceive (const void *buf, size_t len);
void OnDrain (void); void OnDrain (void);
void OnEOF (void);
void OnDisconnect (void); void OnDisconnect (void);
void OnError (oi_error e); void OnError (oi_error e);
void OnTimeout (void); void OnTimeout (void);
v8::Local<v8::Object> GetProtocol (void); v8::Local<v8::Object> GetProtocol (void);
static v8::Local<v8::Object> NewInstance (v8::Local<v8::Function> protocol); static v8::Local<v8::Object> NewServerSideInstance (
v8::Local<v8::Function> protocol,
v8::Handle<v8::Object> server);
private: private:
static void _OnConnect (oi_socket *s) { static void _OnConnect (oi_socket *s) {
@ -52,7 +60,10 @@ private:
static void _OnReceive (oi_socket *s, const void *buf, size_t len) { static void _OnReceive (oi_socket *s, const void *buf, size_t len) {
Connection *connection = static_cast<Connection*> (s->data); Connection *connection = static_cast<Connection*> (s->data);
connection->OnReceive(buf, len); if (len == 0)
connection->OnEOF();
else
connection->OnReceive(buf, len);
} }
static void _OnDrain (oi_socket *s) { static void _OnDrain (oi_socket *s) {

45
test/test-pingpong.js

@ -4,10 +4,9 @@ var port = 12123;
var N = 100; var N = 100;
var count = 0; var count = 0;
var server; function Ponger (socket, server) {
function Ponger (socket) {
this.encoding = "UTF8"; this.encoding = "UTF8";
this.timeout = 0;
this.onConnect = function () { this.onConnect = function () {
puts("got socket."); puts("got socket.");
@ -16,13 +15,21 @@ function Ponger (socket) {
this.onReceive = function (data) { this.onReceive = function (data) {
assertTrue(count <= N); assertTrue(count <= N);
stdout.print ("-"); stdout.print ("-");
if (/QUIT/.exec(data)) { if (/PING/.exec(data)) {
socket.disconnect();
//server.close();
} else if (/PING/.exec(data)) {
socket.send("PONG"); socket.send("PONG");
} }
}; };
this.onEOF = function () {
puts("ponger: onEOF");
socket.send("QUIT");
socket.sendEOF();
};
this.onDisconnect = function () {
puts("ponger: onDisconnect");
server.close();
};
} }
function Pinger (socket) { function Pinger (socket) {
@ -35,27 +42,23 @@ function Pinger (socket) {
this.onReceive = function (data) { this.onReceive = function (data) {
stdout.print("."); stdout.print(".");
assertEquals("PONG", data); assertEquals("PONG", data);
setTimeout(function() { count += 1;
count += 1; if (count < N) {
if (count < N) { socket.send("PING");
socket.send("PING"); } else {
} else { puts("sending FIN");
stdout.write("\n"); socket.sendEOF();
socket.send("QUIT\n"); }
socket.disconnect();
}
}, 10);
}; };
this.onDisconnect = function () { this.onEOF = function () {
puts("socket close."); puts("pinger: onEOF");
assertEquals(N, count); assertEquals(N, count);
server.close();
}; };
} }
function onLoad() { function onLoad() {
server = new TCPServer(Ponger); var server = new TCPServer(Ponger);
server.listen(port); server.listen(port);
var client = new TCPConnection(Pinger); var client = new TCPConnection(Pinger);

Loading…
Cancel
Save