diff --git a/deps/evcom/evcom.c b/deps/evcom/evcom.c index 4267d351e8..0849f8ad0f 100644 --- a/deps/evcom/evcom.c +++ b/deps/evcom/evcom.c @@ -1205,6 +1205,15 @@ evcom_stream_reset_timeout (evcom_stream *stream, float timeout) } } +void +evcom_stream_set_no_delay (evcom_stream *stream, int no_delay) +{ + if (DUPLEX(stream)) { + int flags = no_delay ? 1 : 0; + setsockopt(stream->recvfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags)); + } +} + void evcom_stream_attach (EV_P_ evcom_stream *stream) { diff --git a/deps/evcom/evcom.h b/deps/evcom/evcom.h index 977941692a..644ec9737c 100644 --- a/deps/evcom/evcom.h +++ b/deps/evcom/evcom.h @@ -192,6 +192,7 @@ void evcom_stream_detach (evcom_stream *); void evcom_stream_read_resume (evcom_stream *); void evcom_stream_read_pause (evcom_stream *); void evcom_stream_reset_timeout (evcom_stream *, float timeout); +void evcom_stream_set_no_delay (evcom_stream *, int no_delay); void evcom_stream_write (evcom_stream *, const char *str, size_t len); /* Once the write buffer is drained, evcom_stream_close will shutdown the * writing end of the stream and will close the read end once the server diff --git a/doc/api.html b/doc/api.html index 8cf60291e3..6f33722f59 100644 --- a/doc/api.html +++ b/doc/api.html @@ -1712,6 +1712,16 @@ of 60 seconds (60000 ms).

If timeout is 0, then the idle timeout is disabled.

+
+connection.setNoDelay(noDelay=true) +
+
+

+Disables the Nagle algorithm. By default TCP connections use the Nagle +algorithm, they buffer data before sending it off. Setting noDelay will +immediately fire off data each time connection.send() is called. +

+

DNS

Here is an example of which resolves "www.google.com" then reverse @@ -1922,7 +1932,7 @@ init (Handle<Object> target)

diff --git a/doc/api.txt b/doc/api.txt index 9e211cd9d0..c3525938a6 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -1081,6 +1081,10 @@ of 60 seconds (60000 ms). + If +timeout+ is 0, then the idle timeout is disabled. ++connection.setNoDelay(noDelay=true)+:: +Disables the Nagle algorithm. By default TCP connections use the Nagle +algorithm, they buffer data before sending it off. Setting +noDelay+ will +immediately fire off data each time +connection.send()+ is called. === DNS diff --git a/doc/node.1 b/doc/node.1 index 368230a923..f04a2e68a1 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -1,11 +1,11 @@ .\" Title: node .\" Author: .\" Generator: DocBook XSL Stylesheets v1.73.2 -.\" Date: 09/21/2009 +.\" Date: 09/23/2009 .\" Manual: .\" Source: .\" -.TH "NODE" "1" "09/21/2009" "" "" +.TH "NODE" "1" "09/23/2009" "" "" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -1639,6 +1639,15 @@ If timeout is 0, then the idle timeout is disabled\. .RE +.PP +connection\.setNoDelay(noDelay=true) +.RS 4 +Disables the Nagle algorithm\. By default TCP connections use the Nagle algorithm, they buffer data before sending it off\. Setting +noDelay +will immediately fire off data each time +connection\.send() +is called\. +.RE .RE .SS "DNS" Here is an example of which resolves "www\.google\.com" then reverse resolves the IP addresses which are returned\. diff --git a/src/net.cc b/src/net.cc index 1bcff35a3e..f86c28cb22 100644 --- a/src/net.cc +++ b/src/net.cc @@ -64,6 +64,7 @@ void Connection::Initialize(v8::Handle target) { NODE_SET_PROTOTYPE_METHOD(constructor_template, "readPause", ReadPause); NODE_SET_PROTOTYPE_METHOD(constructor_template, "readResume", ReadResume); NODE_SET_PROTOTYPE_METHOD(constructor_template, "setTimeout", SetTimeout); + NODE_SET_PROTOTYPE_METHOD(constructor_template, "setNoDelay", SetNoDelay); constructor_template->PrototypeTemplate()->SetAccessor( READY_STATE_SYMBOL, @@ -332,6 +333,20 @@ Handle Connection::ForceClose(const Arguments& args) { return Undefined(); } +Handle Connection::SetNoDelay(const Arguments& args) { + HandleScope scope; + Connection *connection = ObjectWrap::Unwrap(args.Holder()); + + bool no_delay = true; + if (args.Length() > 0) { + no_delay = args[0]->IsTrue(); + } + + connection->SetNoDelay(no_delay); + + return Undefined(); +} + Handle Connection::Send(const Arguments& args) { HandleScope scope; Connection *connection = ObjectWrap::Unwrap(args.Holder()); diff --git a/src/net.h b/src/net.h index 0b682a6600..99a3aa67e3 100644 --- a/src/net.h +++ b/src/net.h @@ -28,6 +28,7 @@ class Connection : public EventEmitter { static v8::Handle ReadPause(const v8::Arguments& args); static v8::Handle ReadResume(const v8::Arguments& args); static v8::Handle SetTimeout(const v8::Arguments& args); + static v8::Handle SetNoDelay(const v8::Arguments& args); static v8::Handle ReadyStateGetter(v8::Local _, const v8::AccessorInfo& info); @@ -70,6 +71,10 @@ class Connection : public EventEmitter { evcom_stream_reset_timeout(&stream_, timeout); } + void SetNoDelay(bool no_delay) { + evcom_stream_set_no_delay(&stream_, no_delay); + } + virtual void OnConnect(); virtual void OnReceive(const void *buf, size_t len); virtual void OnEOF(); diff --git a/test/mjsunit/test-tcp-pingpong.js b/test/mjsunit/test-tcp-pingpong.js index 5c7a3538c9..677317026b 100644 --- a/test/mjsunit/test-tcp-pingpong.js +++ b/test/mjsunit/test-tcp-pingpong.js @@ -17,9 +17,11 @@ function pingPongTest (port, host, on_complete) { assertEquals(socket.remoteAddress, "127.0.0.1"); socket.setEncoding("utf8"); + socket.setNoDelay(); socket.timeout = 0; socket.addListener("receive", function (data) { + puts("server got: " + JSON.stringify(data)); assertEquals("open", socket.readyState); assertTrue(count <= N); if (/PING/.exec(data)) {