{"id":8608,"date":"2016-01-13T21:30:07","date_gmt":"2016-01-13T21:30:07","guid":{"rendered":"https:\/\/wp.okra.host\/article\/spawning-multiple-tcp-daemons-in-a-single-app\/"},"modified":"2021-03-07T14:34:00","modified_gmt":"2021-03-07T13:34:00","slug":"spawning-multiple-tcp-daemons-in-a-single-app","status":"publish","type":"ht_kb","link":"https:\/\/kb.okra.host\/de\/article\/spawning-multiple-tcp-daemons-in-a-single-app\/","title":{"rendered":"Spawning multiple TCP daemons in a single app"},"content":{"rendered":"<h2 id=\"overview\" >\u00dcbersicht<\/h2>\n<p>Node\u00a0applications may bind to a TCP port using <code><a href=\"https:\/\/nodejs.org\/api\/net.html#net_server_listen_port_hostname_backlog_callback\">listen<\/a>(<em>&lt;PORT NUMBER&gt;<\/em>)<\/code>, provided of course the <em>PORT NUMBER<\/em> is one <a href=\"https:\/\/kb.okra.host\/de\/terminal\/listening-ports\/\">allocated<\/a> to your account.\u00a0Passenger replaces this listen()\u00a0method with a <a href=\"https:\/\/github.com\/phusion\/passenger\/blob\/stable-5.0\/src\/helper-scripts\/node-loader.js\">built-in method<\/a> that, instead of listening on a TCP\u00a0port, creates a local UNIX socket for communication with the web server (<em>see\u00a0<code>installServer()<\/code>\u00a0in <a href=\"https:\/\/github.com\/phusion\/passenger\/blob\/stable-5.0\/src\/helper-scripts\/node-loader.js\">source<\/a><\/em>).<\/p>\n<p>By creating a socket, no TCP ports are consumed, traffic may only be accessed from\u00a0within the server, and the server must know the socket path. This is great for security, but\u00a0if an app spawns another process, like a <a href=\"https:\/\/www.npmjs.com\/package\/socket.io\">Socket.IO<\/a>, that also calls listen(), then the app fails with:<\/p>\n<blockquote>\n<pre class=\"lang-js prettyprint prettyprinted\">App 28096 stderr: Error: http.Server.listen() was called more than once, which is not allowed because Phusion Passenger is in auto-install mode. This means that the first http.Server object for which listen() is called, is automatically installed as the Phusion Passenger request handler. If you want to create and listen on multiple http. Server object then you should disable auto-install mode.<\/pre>\n<\/blockquote>\n<h2 id=\"cause\" >Ursache<\/h2>\n<p><a href=\"https:\/\/nodejs.org\/api\/net.html#net_server_listen_port_hostname_backlog_callback\">listen<\/a>() is overwritten to create a UNIX socket to communicate with the HTTP server, instead of a TCP socket. This obviates the need to use a proxy passthru to Node applications, but carries a limitation of only 1 listen() invocation per application.<\/p>\n<h2 id=\"solution\" >L\u00f6sung<\/h2>\n<p>Configure PhusionPassenger to disable overwriting listen() via <code>autoInstall: false<\/code>\u00a0 and use the special port, &#8220;<code>passenger<\/code>&#8220;, to create a UNIX socket for the application that serves to handle application\u00a0requests. Any subsequent daemon spawned, for example a backend\u00a0job service, may operate without modification:<\/p>\n<pre class=\"lang-js prettyprint prettyprinted\" data-language=\"javascript\"><code>var http = require('http'),\r\n httpProxy = require('http-proxy');\r\n\r\n\/\/ disable implicit listen() overwrite\r\nif (typeof(PhusionPassenger) != 'undefined') {\r\n PhusionPassenger.configure({ autoInstall: false });\r\n}\r\n\r\n\/\/ explicitly listen on a Passenger socket for communication with the\r\n\/\/ web server\r\nhttpProxy.createServer(9000, 'localhost').listen('passenger');\r\n\r\n\/\/ create a second server on port 9000; this port should be a port\r\n\/\/ allocated to your account\r\nvar target_server = http.createServer(function (req, res) {\r\n res.writeHead(200, { 'Content-Type': 'text\/plain' });\r\n res.write('request successfully proxied!' + 'n' + JSON.stringify(req.headers, true, 2));\r\n res.end();\r\n}).listen(9000);<\/code><\/pre>\n<h2 id=\"see-also\" >Siehe auch<\/h2>\n<ul>\n<li><a href=\"http:\/\/stackoverflow.com\/questions\/20645231\/phusion-passenger-error-http-server-listen-was-called-more-than-once\/20645549\">Phusion Passenger\u00a0Error: http.Server.listen() was called more than once<\/a> (StackOverflow)<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Overview Node\u00a0applications may bind to a TCP port using listen(&lt;PORT NUMBER&gt;), provided of course the PORT NUMBER is one allocated to your account.\u00a0Passenger replaces this listen()\u00a0method with a built-in method that, instead of listening on a TCP\u00a0port, creates a local UNIX socket for communication with the web server (see\u00a0installServer()\u00a0in source)&#8230;.<\/p>","protected":false},"author":1,"comment_status":"open","ping_status":"closed","template":"","format":"standard","meta":{"footnotes":""},"ht-kb-category":[62],"ht-kb-tag":[],"class_list":["post-8608","ht_kb","type-ht_kb","status-publish","format-standard","hentry","ht_kb_category-node"],"_links":{"self":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb\/8608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb"}],"about":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/types\/ht_kb"}],"author":[{"embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/comments?post=8608"}],"version-history":[{"count":1,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb\/8608\/revisions"}],"predecessor-version":[{"id":8609,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb\/8608\/revisions\/8609"}],"wp:attachment":[{"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/media?parent=8608"}],"wp:term":[{"taxonomy":"ht_kb_category","embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb-category?post=8608"},{"taxonomy":"ht_kb_tag","embeddable":true,"href":"https:\/\/kb.okra.host\/de\/wp-json\/wp\/v2\/ht-kb-tag?post=8608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}