The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.
Please select the desired protocol below to get the URL.
This URL has Read-Only access.
main_repo / src / net.cc @ 90fc8d36
History | View | Annotate | Download (16.5 KB)
1 |
#include "net.h" |
---|---|
2 |
#include "node.h" |
3 |
|
4 |
#include <oi_socket.h> |
5 |
#include <oi_buf.h> |
6 |
|
7 |
#include <assert.h> |
8 |
#include <stdlib.h> |
9 |
#include <string.h> |
10 |
#include <strings.h> |
11 |
|
12 |
#include <sys/types.h> |
13 |
#include <sys/socket.h> |
14 |
#include <netdb.h> |
15 |
|
16 |
using namespace v8; |
17 |
|
18 |
static Persistent<FunctionTemplate> socket_template;
|
19 |
|
20 |
#define ON_CONNECT_SYMBOL String::NewSymbol("onConnect") |
21 |
#define ON_CONNECTION_SYMBOL String::NewSymbol("onConnection") |
22 |
#define ON_READ_SYMBOL String::NewSymbol("onRead") |
23 |
|
24 |
static const struct addrinfo tcp_hints = |
25 |
/* ai_flags */ { AI_PASSIVE
|
26 |
/* ai_family */ , AF_UNSPEC
|
27 |
/* ai_socktype */ , SOCK_STREAM
|
28 |
/* ai_protocol */ , 0 |
29 |
/* ai_addrlen */ , 0 |
30 |
/* ai_addr */ , NULL |
31 |
/* ai_canonname */ , NULL |
32 |
/* ai_next */ , NULL |
33 |
}; |
34 |
|
35 |
class Server { |
36 |
public:
|
37 |
Server (Handle<Object> handle, int backlog);
|
38 |
~Server (); |
39 |
|
40 |
static Handle<Value> New (const Arguments& args); |
41 |
static Handle<Value> ListenTCP (const Arguments& args); |
42 |
static Handle<Value> Close (const Arguments& args); |
43 |
|
44 |
private:
|
45 |
static oi_socket* OnConnection (oi_server *, struct sockaddr *, socklen_t); |
46 |
static Server* Unwrap (Handle<Object> handle);
|
47 |
static void MakeWeak (Persistent<Value> _, void *data); |
48 |
oi_server server_; |
49 |
Persistent<Object> handle_; |
50 |
}; |
51 |
|
52 |
class Socket { |
53 |
public:
|
54 |
Socket (Handle<Object> handle, double timeout);
|
55 |
~Socket (); |
56 |
|
57 |
void SetEncoding (Handle<Value>);
|
58 |
void SetTimeout (double); |
59 |
|
60 |
static Handle<Value> New (const Arguments& args); |
61 |
static Handle<Value> Write (const Arguments& args); |
62 |
static Handle<Value> Close (const Arguments& args); |
63 |
static Handle<Value> ConnectTCP (const Arguments& args); |
64 |
static Handle<Value> SetEncoding (const Arguments& args); |
65 |
|
66 |
private:
|
67 |
static void OnConnect (oi_socket *socket); |
68 |
static void OnRead (oi_socket *s, const void *buf, size_t count); |
69 |
static void OnDrain (oi_socket *s); |
70 |
static void OnError (oi_socket *s, oi_error e); |
71 |
static void OnClose (oi_socket *s); |
72 |
static void OnTimeout (oi_socket *s); |
73 |
|
74 |
static int Resolve (eio_req *req); |
75 |
static int AfterResolve (eio_req *req); |
76 |
|
77 |
static Socket* Unwrap (Handle<Object> handle);
|
78 |
static void MakeWeak (Persistent<Value> _, void *data); |
79 |
|
80 |
enum {UTF8, RAW} encoding_;
|
81 |
oi_socket socket_; |
82 |
Persistent<Object> handle_; |
83 |
|
84 |
char *host_;
|
85 |
char *port_;
|
86 |
|
87 |
friend class Server; |
88 |
}; |
89 |
|
90 |
Server::Server (Handle<Object> handle, int backlog)
|
91 |
{ |
92 |
oi_server_init(&server_, backlog); |
93 |
server_.on_connection = Server::OnConnection; |
94 |
// server_.on_error = Server::OnError;
|
95 |
server_.data = this;
|
96 |
|
97 |
HandleScope scope; |
98 |
handle_ = Persistent<Object>::New(handle); |
99 |
handle_->SetInternalField(0, External::New(this)); |
100 |
handle_.MakeWeak(this, Server::MakeWeak);
|
101 |
} |
102 |
|
103 |
Server::~Server () |
104 |
{ |
105 |
HandleScope scope; |
106 |
oi_server_close(&server_); |
107 |
oi_server_detach(&server_); |
108 |
handle_.Dispose(); |
109 |
handle_.Clear(); // necessary?
|
110 |
} |
111 |
|
112 |
Handle<Value> |
113 |
Server::New (const Arguments& args)
|
114 |
{ |
115 |
HandleScope scope; |
116 |
|
117 |
int backlog = 1024; // default |
118 |
if (args.Length() > 0 && args[0]->IsNumber()) |
119 |
backlog = args[0]->IntegerValue();
|
120 |
|
121 |
Server *server = new Server(args.Holder(), backlog);
|
122 |
if(server == NULL) |
123 |
return Undefined(); // XXX raise error? |
124 |
|
125 |
return args.This();
|
126 |
} |
127 |
|
128 |
Handle<Value> |
129 |
Server::ListenTCP (const Arguments& args)
|
130 |
{ |
131 |
if (args.Length() < 2) return Undefined(); |
132 |
HandleScope scope; |
133 |
|
134 |
Server *server = Server::Unwrap(args.Holder()); |
135 |
|
136 |
String::AsciiValue port(args[0]);
|
137 |
|
138 |
int callback_index = 1; |
139 |
char *host = NULL; |
140 |
if (args[1]->IsString()) { |
141 |
callback_index = 2;
|
142 |
String::AsciiValue host_v(args[1]->ToString());
|
143 |
if(args[1]->IsString()) host = *host_v; |
144 |
} |
145 |
|
146 |
// For servers call getaddrinfo inline. This is blocking but it shouldn't
|
147 |
// matter--ever. If someone actually complains then simply swap it out
|
148 |
// with a libeio call.
|
149 |
struct addrinfo *address = NULL; |
150 |
int r = getaddrinfo(host, *port, &tcp_hints, &address);
|
151 |
if (r != 0) |
152 |
return ThrowException(String::New("Error looking up hostname")); |
153 |
|
154 |
if (!args[callback_index]->IsFunction())
|
155 |
return ThrowException(String::New("Must supply onConnection callback")); |
156 |
|
157 |
server->handle_->Set(ON_CONNECTION_SYMBOL, args[callback_index]); |
158 |
|
159 |
r = oi_server_listen(&server->server_, address); |
160 |
if (r != 0) |
161 |
return ThrowException(String::New("Error listening on port")); |
162 |
oi_server_attach(EV_DEFAULT_UC_ &server->server_); |
163 |
|
164 |
freeaddrinfo(address); |
165 |
|
166 |
return Undefined();
|
167 |
} |
168 |
|
169 |
Handle<Value> |
170 |
Server::Close (const Arguments& args)
|
171 |
{ |
172 |
HandleScope scope; |
173 |
Server *server = Server::Unwrap(args.Holder()); |
174 |
oi_server_close(&server->server_); |
175 |
return Undefined();
|
176 |
} |
177 |
|
178 |
oi_socket* |
179 |
Server::OnConnection (oi_server *s, struct sockaddr *remote_addr, socklen_t remote_addr_len)
|
180 |
{ |
181 |
Server *server = static_cast<Server*> (s->data);
|
182 |
HandleScope scope; |
183 |
|
184 |
Local<Object> socket_handle = socket_template->GetFunction()->NewInstance(); |
185 |
Socket *socket = new Socket(socket_handle, 60.0); |
186 |
socket->handle_->Delete(String::NewSymbol("connectTCP"));
|
187 |
|
188 |
Local<Value> callback_v = server->handle_->Get(ON_CONNECTION_SYMBOL); |
189 |
if (!callback_v->IsFunction())
|
190 |
return NULL; // produce error? |
191 |
|
192 |
Local<Function> callback = Local<Function>::Cast(callback_v); |
193 |
const int argc = 1; |
194 |
Local<Value> argv[argc]; |
195 |
argv[0] = Local<Value>::New(socket->handle_);
|
196 |
callback->Call(server->handle_, argc, argv); |
197 |
|
198 |
return &socket->socket_;
|
199 |
} |
200 |
|
201 |
Server* |
202 |
Server::Unwrap (Handle<Object> handle) |
203 |
{ |
204 |
HandleScope scope; |
205 |
Handle<External> field = Handle<External>::Cast(handle->GetInternalField(0));
|
206 |
Server* server = static_cast<Server*>(field->Value());
|
207 |
return server;
|
208 |
} |
209 |
|
210 |
void
|
211 |
Server::MakeWeak (Persistent<Value> _, void *data)
|
212 |
{ |
213 |
Server *s = static_cast<Server*> (data);
|
214 |
delete s;
|
215 |
} |
216 |
|
217 |
Handle<Value> |
218 |
Socket::New(const Arguments& args)
|
219 |
{ |
220 |
if (args.Length() > 1) |
221 |
return Undefined();
|
222 |
|
223 |
HandleScope scope; |
224 |
|
225 |
// Default options
|
226 |
double timeout = 60.0; // in seconds |
227 |
enum {UTF8, RAW} encoding ;
|
228 |
|
229 |
// Set options from argument.
|
230 |
if (args.Length() == 1 && args[0]->IsObject()) { |
231 |
Local<Object> options = args[0]->ToObject();
|
232 |
Local<Value> timeout_value = options->Get(String::NewSymbol("timeout"));
|
233 |
Local<Value> encoding_value = options->Get(String::NewSymbol("encoding"));
|
234 |
|
235 |
if (timeout_value->IsNumber()) {
|
236 |
// timeout is specified in milliseconds like other time
|
237 |
// values in javascript
|
238 |
timeout = timeout_value->NumberValue() / 1000;
|
239 |
} |
240 |
|
241 |
if (encoding_value->IsString()) {
|
242 |
Local<String> encoding_string = encoding_value->ToString(); |
243 |
char buf[5]; // need enough room for "utf8" or "raw" |
244 |
encoding_string->WriteAscii(buf, 0, 4); |
245 |
buf[4] = '\0'; |
246 |
if(strcasecmp(buf, "utf8") == 0) encoding = UTF8; |
247 |
} |
248 |
} |
249 |
|
250 |
Socket *s = new Socket(args.Holder(), timeout);
|
251 |
if(s == NULL) |
252 |
return Undefined(); // XXX raise error? |
253 |
|
254 |
return args.This();
|
255 |
} |
256 |
|
257 |
void
|
258 |
Socket::SetEncoding (Handle<Value> encoding_value) |
259 |
{ |
260 |
if (encoding_value->IsString()) {
|
261 |
HandleScope scope; |
262 |
Local<String> encoding_string = encoding_value->ToString(); |
263 |
char buf[5]; // need enough room for "utf8" or "raw" |
264 |
encoding_string->WriteAscii(buf, 0, 4); |
265 |
buf[4] = '\0'; |
266 |
if(strcasecmp(buf, "utf8") == 0) |
267 |
encoding_ = UTF8; |
268 |
else
|
269 |
encoding_ = RAW; |
270 |
} |
271 |
} |
272 |
|
273 |
Socket* |
274 |
Socket::Unwrap (Handle<Object> handle) |
275 |
{ |
276 |
HandleScope scope; |
277 |
Handle<External> field = Handle<External>::Cast(handle->GetInternalField(0));
|
278 |
Socket* socket = static_cast<Socket*>(field->Value());
|
279 |
return socket;
|
280 |
} |
281 |
|
282 |
Handle<Value> |
283 |
Socket::ConnectTCP (const Arguments& args)
|
284 |
{ |
285 |
if (args.Length() < 1) |
286 |
return Undefined();
|
287 |
|
288 |
HandleScope scope; |
289 |
Socket *socket = Socket::Unwrap(args.Holder()); |
290 |
|
291 |
String::AsciiValue port(args[0]);
|
292 |
socket->port_ = strdup(*port); |
293 |
|
294 |
assert(socket->host_ == NULL);
|
295 |
String::AsciiValue host_v(args[1]->ToString());
|
296 |
if(args[1]->IsString()) { |
297 |
socket->host_ = strdup(*host_v); |
298 |
} |
299 |
|
300 |
if(args[2]->IsFunction()) { |
301 |
socket->handle_->Set(ON_CONNECT_SYMBOL , args[2]);
|
302 |
} |
303 |
|
304 |
/* For the moment I will do DNS lookups in the thread pool. This is
|
305 |
* sub-optimal and cannot handle massive numbers of requests but it is
|
306 |
* quite portable.
|
307 |
* In the future I will move to a system using adns or udns:
|
308 |
* http://lists.schmorp.de/pipermail/libev/2009q1/000632.html
|
309 |
*/
|
310 |
node_eio_warmup(); |
311 |
eio_req *req = eio_custom (Socket::Resolve, EIO_PRI_DEFAULT, Socket::AfterResolve, socket); |
312 |
|
313 |
return Undefined();
|
314 |
} |
315 |
|
316 |
/* This function is executed in the thread pool. It cannot touch anything! */
|
317 |
int
|
318 |
Socket::Resolve (eio_req *req) |
319 |
{ |
320 |
Socket *socket = static_cast<Socket*> (req->data);
|
321 |
struct addrinfo *address = NULL; |
322 |
|
323 |
req->result = getaddrinfo(socket->host_, socket->port_, &tcp_hints, &address); |
324 |
|
325 |
req->ptr2 = address; |
326 |
|
327 |
free(socket->host_); |
328 |
socket->host_ = NULL;
|
329 |
|
330 |
free(socket->port_); |
331 |
socket->port_ = NULL;
|
332 |
|
333 |
return 0; |
334 |
} |
335 |
|
336 |
int
|
337 |
Socket::AfterResolve (eio_req *req) |
338 |
{ |
339 |
Socket *socket = static_cast<Socket*> (req->data);
|
340 |
struct addrinfo *address = static_cast<struct addrinfo *>(req->ptr2); |
341 |
req->ptr2 = NULL;
|
342 |
|
343 |
int r = 0; |
344 |
if (req->result == 0) { |
345 |
r = oi_socket_connect (&socket->socket_, address); |
346 |
} |
347 |
if (address)
|
348 |
freeaddrinfo(address); |
349 |
|
350 |
// no error. return.
|
351 |
if(r == 0 && req->result == 0) { |
352 |
oi_socket_attach (EV_DEFAULT_UC_ &socket->socket_); |
353 |
return 0; |
354 |
} |
355 |
|
356 |
HandleScope scope; |
357 |
Handle<Value> onconnect_value = socket->handle_->Get(ON_CONNECT_SYMBOL); |
358 |
if (!onconnect_value->IsFunction()) return 0; |
359 |
Handle<Function> onconnect = Handle<Function>::Cast(onconnect_value); |
360 |
|
361 |
TryCatch try_catch; |
362 |
const int argc = 1; |
363 |
Local<Value> argv[argc]; |
364 |
argv[0] = Integer::New(r | req->result); // FIXME very stupid error code. |
365 |
|
366 |
onconnect->Call(socket->handle_, argc, argv); |
367 |
if(try_catch.HasCaught())
|
368 |
node_fatal_exception(try_catch); |
369 |
|
370 |
return 0; |
371 |
} |
372 |
|
373 |
Handle<Value> |
374 |
Socket::Close (const Arguments& args)
|
375 |
{ |
376 |
HandleScope scope; |
377 |
Socket *socket = Socket::Unwrap(args.Holder()); |
378 |
oi_socket_close(&socket->socket_); |
379 |
return Undefined();
|
380 |
} |
381 |
|
382 |
void
|
383 |
Socket::MakeWeak (Persistent<Value> _, void *data)
|
384 |
{ |
385 |
Socket *s = static_cast<Socket*> (data);
|
386 |
delete s;
|
387 |
} |
388 |
|
389 |
Socket::Socket(Handle<Object> handle, double timeout)
|
390 |
{ |
391 |
oi_socket_init(&socket_, timeout); |
392 |
socket_.on_connect = Socket::OnConnect; |
393 |
socket_.on_read = Socket::OnRead; |
394 |
// socket_.on_drain = Socket::OnDrain;
|
395 |
// socket_.on_error = Socket::OnError;
|
396 |
socket_.on_close = Socket::OnClose; |
397 |
socket_.on_timeout = Socket::OnTimeout; |
398 |
socket_.data = this;
|
399 |
|
400 |
HandleScope scope; |
401 |
handle_ = Persistent<Object>::New(handle); |
402 |
handle_->SetInternalField(0, External::New(this)); |
403 |
handle_.MakeWeak(this, Socket::MakeWeak);
|
404 |
|
405 |
encoding_ = UTF8; // default encoding.
|
406 |
host_ = NULL;
|
407 |
port_ = NULL;
|
408 |
} |
409 |
|
410 |
Socket::~Socket () |
411 |
{ |
412 |
HandleScope scope; |
413 |
oi_socket_close(&socket_); |
414 |
oi_socket_detach(&socket_); |
415 |
free(host_); |
416 |
free(port_); |
417 |
|
418 |
handle_->SetInternalField(0, Undefined());
|
419 |
handle_->Delete(String::NewSymbol("write"));
|
420 |
handle_->Delete(String::NewSymbol("close"));
|
421 |
|
422 |
handle_.Dispose(); |
423 |
handle_.Clear(); // necessary?
|
424 |
} |
425 |
|
426 |
Handle<Value> |
427 |
Socket::SetEncoding (const Arguments& args)
|
428 |
{ |
429 |
HandleScope scope; |
430 |
Socket *socket = Socket::Unwrap(args.Holder()); |
431 |
socket->SetEncoding(args[0]);
|
432 |
return Undefined();
|
433 |
} |
434 |
|
435 |
Handle<Value> |
436 |
Socket::Write (const Arguments& args)
|
437 |
{ |
438 |
HandleScope scope; |
439 |
|
440 |
Socket *socket = Socket::Unwrap(args.Holder()); |
441 |
|
442 |
// TODO support a callback using buf->on_release
|
443 |
|
444 |
if (args[0] == Null()) { |
445 |
oi_socket_write_eof(&socket->socket_); |
446 |
|
447 |
} else if (args[0]->IsString()) { |
448 |
// utf8 encoding
|
449 |
Local<String> s = args[0]->ToString();
|
450 |
size_t length = s->Utf8Length(); |
451 |
oi_buf *buf = oi_buf_new2(length); |
452 |
s->WriteUtf8(buf->base, length); |
453 |
oi_socket_write(&socket->socket_, buf); |
454 |
|
455 |
} else if (args[0]->IsArray()) { |
456 |
// raw encoding
|
457 |
Handle<Array> array = Handle<Array>::Cast(args[0]);
|
458 |
size_t length = array->Length(); |
459 |
oi_buf *buf = oi_buf_new2(length); |
460 |
for (int i = 0; i < length; i++) { |
461 |
Local<Value> int_value = array->Get(Integer::New(i)); |
462 |
buf->base[i] = int_value->IntegerValue(); |
463 |
} |
464 |
oi_socket_write(&socket->socket_, buf); |
465 |
|
466 |
} else return ThrowException(String::New("Bad argument")); |
467 |
|
468 |
return Undefined();
|
469 |
} |
470 |
|
471 |
void
|
472 |
Socket::OnConnect (oi_socket *s) |
473 |
{ |
474 |
Socket *socket = static_cast<Socket*> (s->data);
|
475 |
|
476 |
HandleScope scope; |
477 |
|
478 |
Handle<Value> on_connect_value = socket->handle_->Get(ON_CONNECT_SYMBOL); |
479 |
if (!on_connect_value->IsFunction())
|
480 |
return;
|
481 |
Handle<Function> on_connect = Handle<Function>::Cast(on_connect_value); |
482 |
|
483 |
TryCatch try_catch; |
484 |
const int argc = 1; |
485 |
Local<Value> argv[argc]; |
486 |
argv[0] = Integer::New(0); |
487 |
|
488 |
Handle<Value> r = on_connect->Call(socket->handle_, argc, argv); |
489 |
|
490 |
if(try_catch.HasCaught())
|
491 |
node_fatal_exception(try_catch); |
492 |
} |
493 |
|
494 |
void
|
495 |
Socket::OnRead (oi_socket *s, const void *buf, size_t count) |
496 |
{ |
497 |
Socket *socket = static_cast<Socket*> (s->data);
|
498 |
HandleScope scope; |
499 |
|
500 |
Handle<Value> onread_value = socket->handle_->Get(ON_READ_SYMBOL); |
501 |
if (!onread_value->IsFunction()) return; |
502 |
Handle<Function> onread = Handle<Function>::Cast(onread_value); |
503 |
|
504 |
const int argc = 1; |
505 |
Handle<Value> argv[argc]; |
506 |
|
507 |
if(count) {
|
508 |
if(socket->encoding_ == UTF8) {
|
509 |
// utf8 encoding
|
510 |
Handle<String> chunk = String::New((const char*)buf, count); |
511 |
argv[0] = chunk;
|
512 |
} else {
|
513 |
// raw encoding
|
514 |
Local<Array> array = Array::New(count); |
515 |
for (int i = 0; i < count; i++) { |
516 |
char val = static_cast<const char*>(buf)[i]; |
517 |
array->Set(Integer::New(i), Integer::New(val)); |
518 |
} |
519 |
argv[0] = array;
|
520 |
} |
521 |
} else {
|
522 |
argv[0] = Local<Value>::New(Null());
|
523 |
} |
524 |
|
525 |
TryCatch try_catch; |
526 |
|
527 |
Handle<Value> r = onread->Call(socket->handle_, argc, argv); |
528 |
|
529 |
if(try_catch.HasCaught())
|
530 |
node_fatal_exception(try_catch); |
531 |
} |
532 |
|
533 |
void
|
534 |
Socket::OnClose (oi_socket *s) |
535 |
{ |
536 |
Socket *socket = static_cast<Socket*> (s->data);
|
537 |
HandleScope scope; |
538 |
|
539 |
Handle<Value> onclose_value = socket->handle_->Get( String::NewSymbol("onClose") );
|
540 |
if (!onclose_value->IsFunction()) {
|
541 |
delete socket;
|
542 |
return;
|
543 |
} |
544 |
Handle<Function> onclose = Handle<Function>::Cast(onclose_value); |
545 |
|
546 |
TryCatch try_catch; |
547 |
|
548 |
Handle<Value> r = onclose->Call(socket->handle_, 0, NULL); |
549 |
|
550 |
if(try_catch.HasCaught())
|
551 |
node_fatal_exception(try_catch); |
552 |
|
553 |
delete socket;
|
554 |
} |
555 |
|
556 |
void
|
557 |
Socket::OnDrain (oi_socket *s) |
558 |
{ |
559 |
Socket *socket = static_cast<Socket*> (s->data);
|
560 |
HandleScope scope; |
561 |
|
562 |
Handle<Value> ondrain_value = socket->handle_->Get( String::NewSymbol("onDrain") );
|
563 |
if (!ondrain_value->IsFunction()) return; |
564 |
Handle<Function> ondrain = Handle<Function>::Cast(ondrain_value); |
565 |
|
566 |
TryCatch try_catch; |
567 |
|
568 |
Handle<Value> r = ondrain->Call(socket->handle_, 0, NULL); |
569 |
|
570 |
if(try_catch.HasCaught())
|
571 |
node_fatal_exception(try_catch); |
572 |
} |
573 |
|
574 |
|
575 |
void
|
576 |
Socket::OnError (oi_socket *s, oi_error e) |
577 |
{ |
578 |
Socket *socket = static_cast<Socket*> (s->data);
|
579 |
HandleScope scope; |
580 |
|
581 |
Handle<Value> onerror_value = socket->handle_->Get( String::NewSymbol("onError") );
|
582 |
if (!onerror_value->IsFunction()) return; |
583 |
Handle<Function> onerror = Handle<Function>::Cast(onerror_value); |
584 |
|
585 |
TryCatch try_catch; |
586 |
|
587 |
Handle<Value> r = onerror->Call(socket->handle_, 0, NULL); |
588 |
|
589 |
if(try_catch.HasCaught())
|
590 |
node_fatal_exception(try_catch); |
591 |
} |
592 |
|
593 |
void
|
594 |
Socket::OnTimeout (oi_socket *s) |
595 |
{ |
596 |
Socket *socket = static_cast<Socket*> (s->data);
|
597 |
HandleScope scope; |
598 |
|
599 |
Handle<Value> ontimeout_value = socket->handle_->Get( String::NewSymbol("onTimeout") );
|
600 |
if (!ontimeout_value->IsFunction()) return; |
601 |
Handle<Function> ontimeout = Handle<Function>::Cast(ontimeout_value); |
602 |
|
603 |
TryCatch try_catch; |
604 |
|
605 |
Handle<Value> r = ontimeout->Call(socket->handle_, 0, NULL); |
606 |
|
607 |
if(try_catch.HasCaught())
|
608 |
node_fatal_exception(try_catch); |
609 |
} |
610 |
|
611 |
void
|
612 |
NodeInit_net (Handle<Object> target) |
613 |
{ |
614 |
HandleScope scope; |
615 |
|
616 |
Local<FunctionTemplate> socket_template_local = FunctionTemplate::New(Socket::New); |
617 |
socket_template = Persistent<FunctionTemplate>::New(socket_template_local); |
618 |
socket_template->InstanceTemplate()->SetInternalFieldCount(1);
|
619 |
target->Set(String::NewSymbol("Socket"), socket_template->GetFunction());
|
620 |
|
621 |
NODE_SET_METHOD(socket_template->InstanceTemplate(), "connectTCP", Socket::ConnectTCP);
|
622 |
//NODE_SET_METHOD(socket_template->InstanceTemplate(), "connectUNIX", Socket::ConnectUNIX);
|
623 |
NODE_SET_METHOD(socket_template->InstanceTemplate(), "write", Socket::Write);
|
624 |
NODE_SET_METHOD(socket_template->InstanceTemplate(), "close", Socket::Close);
|
625 |
NODE_SET_METHOD(socket_template->InstanceTemplate(), "setEncoding", Socket::SetEncoding);
|
626 |
|
627 |
Local<FunctionTemplate> server_template = FunctionTemplate::New(Server::New); |
628 |
server_template->InstanceTemplate()->SetInternalFieldCount(1);
|
629 |
target->Set(String::NewSymbol("Server"), server_template->GetFunction());
|
630 |
|
631 |
NODE_SET_METHOD(server_template->InstanceTemplate(), "listenTCP", Server::ListenTCP);
|
632 |
NODE_SET_METHOD(server_template->InstanceTemplate(), "close", Server::Close);
|
633 |
} |
634 |
|