data transfer from HTTP server to TCP server - node.js

I'm working on a project where in I've a .Net client connected to a node TCP server. This TCP server in turn needs to receive data from another node HTTP server. So, this HTTP server is receiving some data and it needs to forward it to the TCP server. And then the TCP server needs to broadcast it to all its .Net clients.
I'm stuck with the data transfer part (tried using sockets, bt not quite confident about it).
say, the HTTP server is defined as:
var httpServer = http.createServer(function(req,res){
res.writeHead(200, { 'Content-type': 'text/html' });
var parsed = url.parse(req.url, true);
output = parsed.query.id;
}).listen(http_PORT);
where the variable 'output' is contrived from a URL sent from a third server. So, I need to pass this variable 'output' to a TCP server running on some other port.
Any help would be appreciated.
Regards,
Abinash.

You can use WCF with TCP binding for this.
Http page will ping WCF service.

Related

socket.io in existing node.js project

I am looking to implement real-time updates in my application that has a node.js backend. I want to use socket.io for this and I understand the library that needs to be implemented. However, I already have a node.js server running:
app.listen(process.env.PORT, () => {
console.log("Server is up and running")
})
The question is fairly simple: is it possible to use the same server with the same port to listen for socket.io connections, or should I run this entirely on a different server or just open another port for this? Because what I often see in the examples is that it listens to http. See below.
What I usually see (this example comes from this post)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000, function () {
console.log('listening on *:3000');
});
Now, if I would use the same server and port, how could I also listen for incoming socket.io requests or emit to its clients? Can I just keep listening with app.listen and will it also connect to socket.io?
In short yes, the socket connection starts as an http request on the same address and port.
The WebSocket protocol was designed to work well with the existing Web
infrastructure. As part of this design principle, the protocol
specification defines that the WebSocket connection starts its life as
an HTTP connection, guaranteeing full backwards compatibility with the
pre-WebSocket world. The protocol switch from HTTP to WebSocket is
referred to as a the WebSocket handshake.
At this point the HTTP connection breaks down and is replaced by the
WebSocket connection over the same underlying TCP/IP connection. The
WebSocket connection uses the same ports as HTTP (80) and HTTPS (443),
by default.
https://websocket.org/aboutwebsocket.html

Socket.io connection event not fired on server

I am trying to build a command-line chat room using Node.js and Socket.io.
This is my server-side code so far, I have tried this with both http initialisations (with express, like on the official website's tutorial, and without it):
#app = require('express')()
#http = require('http').Server(app)
http = require('http').createServer()
io = require('socket.io')(http)
io.sockets.on 'connect', (socket) ->
console.log 'a user connected'
http.listen 3000, () ->
console.log 'listening on *:3000'
I start this with nodejs server.js, the "Listening on" is showing up.
If I run lsof -i tcp:3000, the server.js process shows up.
However, when I start this client-side code:
socket = require('socket.io-client')('localhost:3000', {})
socket.on 'connect', (socket) ->
console.log "Connected"
No luck... When I run nodejs client.js, neither "connect" events, from server nor client, are fired!
My questions are :
- What am I doing wrong?
- Is it necessary to start a HTTP server to use it? Sockets are on the transport layer, right? So in theory I don't need a HTTP protocol to trade messages.
If this is a server to server connection and you're only making a socket.io connection (not also setting it up for regular HTTP connections), then this code shows the simple way for just a socket.io connection:
Listening socket.io-only server
// Load the library and initialize a server on port 3000
// This will create an underlying HTTP server, start it and bind socket.io to it
const io = require('socket.io')(3000);
// listen for incoming client connections and log connect and disconnect events
io.on('connection', function (socket) {
console.log("socket.io connect: ", socket.id);
socket.on('disconnect', function() {
console.log("socket.io disconnect: ", socket.id);
});
});
Node.js socket.io client - connects to another socket.io server
// load the client-side library
const io = require('socket.io-client');
// connect to a server and port
const socket = io('http://localhost:3000');
// listen for successful connection to the server
socket.on('connect', function() {
console.log("socket.io connection: ", socket.id);
});
This code works on my computer. I can run two separate node.js apps on the same host and they can talk to one another and both see the connect and disconnect events.
Some Explaining
The socket.io protocol is initiated by making an HTTP connection to an HTTP server. So, anytime you have a socket.io connection, there is an HTTP server listening somewhere. That HTTP connection is initially sent with some special headers that indicate to the server that this is a request to "upgrade" to the webSocket protocol and some additional security info is included.
This is pretty great reference on how a webSocket connection is initially established. It will show you step by step what happens.
Once both sides agree on the "upgrade" in protocol, then the protocol is switched to webSocket (socket.io is then an additional protocol layer on top of the base webSocket protocol, but the connection is all established at the HTTP/webSocket level). Once the upgrade is agreed upon, the exact same TCP connection that was originally the incoming HTTP connection is repurposed and becomes the webSocket/socket.io connection.
With the socket.io server-side library, you can either create the HTTP server yourself and then pass that to socket.io or you can have socket.io just create one for you. If you're only using socket.io on this server and not also sharing using http server for regular http requests, then you can go either way. The minimal code example above, just lets socket.io create the http server for you transparently and then socket.io binds to it. If you are also fielding regular web requests from the http server, then you would typically create the http server first and then pass it to socket.io so socket.io could bind to the http server you already have.
Then, keep in mind that socket.io is using the webSocket transport. It's just some additional packet structure on top of the webSocket transport. It would akin to agreeing to send JSON across an HTTP connection. HTTP is the host transport and underlying data format. Both sides then agree to format some data in JSON format and send it across HTTP. The socket.io message format sits on top of webSocket in that way.
Your Questions
Is it necessary to start a HTTP server to use it?
Yes, an HTTP server must exist somewhere because all socket.io connections start with an HTTP request to an HTTP server.
Sockets are on the transport layer, right?
The initial connection protocol stack works like this:
TCP <- HTTP protocol
Then, after the protocol upgrade:
TCP <- webSocket <- socket.io
So after the protocol upgrade from HTTP to the webSocket transport, you then have socket.io packet format sitting on top of the webSocket format sitting on top of TCP.
So in theory I don't need a HTTP protocol to trade messages.
No, that is not correct. All connections are initially established with HTTP. Once the upgrade happens to the webSocket transport, HTTP is no longer used.

node.js write directly to the socket underlying http

I have a Node.js http server that occasionally acts as a proxy for some server side code written in a different language.
So sometimes (but not always) http requests are to be passed through to an server application via sockets. The responses coming from the application already contain the http headers.
The problem is that I would like to simply write the application response into the http response stream without worrying about writing the headers and content separately.
I could implement the entire http server using net sockets but I would like to eventually implement a node http framework as the front-end.
Using the http module, is there a way to write directly to the underlying response socket?
When a request comes in, you should be able to access the connection property of the request.
var http = require('http');
http.createServer(function (req, res) {
req.connection.write(/* your data here */);
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Note that if you do this, you are also responsible for closing the connection when done.
You could also just pipe the two streams together.

NodeJS TCP Socket does not show client hostname information

lets say I've created a simple node.js TCP Socket server as follows.
var server = net.createServer(function (socket) {
socket.end("goodbye\n");
});
// listen on port 80, like a webserver would, and configured to accept connections to multiple hosts, ie test.example.com, sdfsdfsdf.example.com, example2.com.
server.listen(80, function() {
address = server.address();
console.log("opened server on %j", address);
});
server.on('connection', function(socket) {
//log('connection data', socket);
log('CONNECTED SOCKET DATA', socket.address());
log('CONNECTED LOCAL, %s:%s', socket.localAddress, socket.localPort);
log('CONNECTED %s:%s', socket.remoteAddress, socket.remotePort);
//How do I find the server hostname that the client connected to?
// eg test.example.com or example2.com
});
Once a tcp connection is made, I want to parse the hostname that the client attempted to connect to. However the socket does not seem to have this information.
The following is what I got when I ran the previous code (removed ip addresses)
CONNECTED SOCKET DATA { port: 80, family: 2, address: '[SERVER IP ADDRESS]' }
CONNECTED LOCAL, undefined:undefined
CONNECTED [CLIENT IP ADDRESS]:13263
I've gone through the nodejs socket documentation but I cant find anything related to host name. The documentation actually says that the socket.localAddress will be an IP Address, with makes it useless in my case.
That information is not available at the TCP layer. You need to look at the Host header at the HTTP layer when a request arrives. This will be available as req.headers.host when a request arrives. http://nodejs.org/docs/latest/api/all.html#all_message_headers
Also based on your comment, trying to run a non-HTTP server on port 80 is asking for trouble. You are going to get connections from web spiders and botnets all the time, so make sure your program properly handles HTTP clients connecting and disconnects them or perhaps sends an HTTP error message.
Joe is correct in the comment that if you are not using HTTP, your custom protocol will need to transmit the "virtual host" name from the client to the server in the first packet/header message of your custom protocol.

Why do nodejs WebSocket implementations not use net.Server?

I am currently experiencing with Websockets.
By reviewing some active projects/implementations like einaros/ws (and others as well) I found out that they implement the server their own. Instead of using the node net module which provides a tcp server. Is there a reason for this approach?
https://github.com/einaros/ws/blob/master/lib/WebSocketServer.js
Regards
Update:
var server = net.createServer(function(c) {
c.on('data', function(data) {
// data is a websocket fragment which has to get parsed
});
// transformToSingleUtfFragment is building a websocket valid
// byte fragment which contains hello as application payload
// and sets the right flags so the receiver knows we have a single text fragment
c.write(transformToSingleUtfFragment('hello'));
c.pipe(c);
});
server.listen(8124, function() { //'listening' listener
console.log('server bound');
});
WebSocket's a a protocol layered on top of normal HTTP.
How it works is basically that the browser sends a UPGRADE HTTP request and then makes use of the HTTP 1.1 keep alive functionality to keep the underlying TCP socket of the HTTP connection open.
The data is then send via the WebSocket Protocol (Rather large RFC behind the link), which itself is built on top of TCP.
Since the HTTP part is required, and you need to re-use the TCP connection from that one, it makes sense to go with the normal HTTP server instead of net.Server. Otherwise you'd had to implement the HTTP handling part yourself.
Implementing the WebSocket Protocol needs to be done in either case, and since any HTTP connection can be upgraded, you can, in theory, simply connect your WebSocket "server" to the normal HTTP Server on Port 80 and thus handle both normal HTTP requests and WebSockets on the same port.

Resources