sharing a TCP socket / port is easy using node.js cluster, but it does not seem possible to do this with UDP dgram.
is there a way to do this either using cluster, by sharing file descriptors between processes or other?
I had a lot of problems with this because node.js doesn't really "fork", it "spawns" or "fork/execs". When I used cluster for a UDP server only ONE of the child processes would receive packets, the last one bound. If you simply "fork()", the OS round robins the incoming packets to each of the children. If you "spawn()" you run into inheritance rights problems with file/socket handles, options have to be set etc. and the underlying node.js udp server may not have applied those options.
I had to write my own extension that simply called the underlying OS fork() and made it work like a normal forking, network server.
Windows doesn't have fork() so this approach won't work and it's probably why node.js doesn't have a normal, plain, garden variety fork(). Doing that would make it non portable to Windows.
1) create a directory, I called mine "util".
2) Put these two files in that directory.
------------------- cut here, name the following "util.cc" -------
#include <v8.h> //needed for extension infrastructure
#include <node.h> //needed for extension infrastructure
#include <iostream> // not part of extension infrastructure, just for the code I'm adding and only while developing to output debugging messages
using namespace node;
using namespace v8;
// The following two functions are examples of the minimum required for a node.js extension that does anything
static Handle<Value> spoon(const Arguments& args)
{
pid_t rval = fork();
if (rval < 0)
{
return ThrowException(Exception::Error(String::New("Unable to fork daemon, pid < 0.")));
}
Handle<Value> n = v8::Number::New(rval);
return n;
}
static Handle<Value> pid(const Arguments& args)
{
pid_t rval = getpid();
Handle<Value> n = v8::Number::New(rval);
return n;
}
extern "C" void init(Handle<Object> target)
{
NODE_SET_METHOD(target, "fork", spoon);
NODE_SET_METHOD(target, "pid", pid);
}
-------- cut here, name the following "wscript" -------
def set_options(opt):
opt.tool_options("compiler_cxx")
def configure(conf):
conf.check_tool("compiler_cxx")
conf.check_tool("node_addon")
def build(bld):
obj = bld.new_task_gen("cxx", "shlib", "node_addon")
obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"]
obj.target = "util"
obj.source = "util.cc"
--------- end of cutting, spare us the cutter ------
3) run "node-waf configure"
If that goes well,
4) run "node-waf"
5) a new directory called "build" will be created, and your extension "build/default/util.node" will have been created. Copy that wherever and use it from within your node program like:
var util = require("util.node");
var pid = util.fork();
Also included in there is a util.pid() function because the process.pid doesn't work right after forking. It delivers the pid of the parent process.
I'm a beginner node extension writer so if this is a naive approach, oh well, but it has served me well so far. Any improvements, as in "simplifications" would be greatly appreciated.
This issue was resolved in node.js v0.10