Search code examples
node.jsexpresshttptcp

How can a TCP/IP server write data on a HTTP server?


Here is my tcp/ip server that listens to IoT sensors sending it data:

const net = require('net')

const server = net.createServer(socket => {
    socket.on('data', data => {
        console.log(data.toString())
    })
}).listen(1234)

I receive the data fine. A line of data received looks like 'DATA,zoneA,20'.

Now I want to write that stream of data to this http server:

const express = require('express')
const morgan = require('morgan')
const app = express()
const bodyParser = require('body-parser')
const {PORT} = 3000

app.use(morgan('tiny'))
app.use(express.json())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))


const catchTCP = async dataLine => {
    dataLine = 'DATA,zoneA,20' 
    try {
        if (dataLine.indexOf("DATA") >= 0) {
            var stream = dataLine.split(",")
            var streamData = {
                zone: stream[1],
                battery: stream[2]
            }
            console.log(streamData)
        }
    } catch(err) {
        console.log("error:", err)
    }
}

catchTCP()

app.listen(PORT, () => console.log(`App listening at http://localhost:${PORT}`))

I would like to replace the 'dataLine' object by an entry point for this TCP/IP data. What would be the best way to forward TCP/IP data to the HTTP server's port?

Both servers run on the same network, so I've been told socket.io would not be the best fit.


Solution

  • Replace the catchTCP function on your HTTP server with a middleware route:

    app.post("/receive", express.text(), function(req, res) {
      var dataLine = req.body;
      /* Your code from catchTCP */
      res.end(); /* finish the HTTP response */
    });
    

    Then your TCP/IP server can send an HTTP request with the following code:

    var s = net.createConnection(PORT, "localhost", function() {
    s.end(`POST /receive HTTP/1.1
    Content-Type: text/plain
    Content-Length: ${data.toString().length}
    
    ${data}`);
    });
    

    This is the TCP/IP-level representation of the HTTP request. But I would not do it that way, I would rather use a proper HTTP client. Which is not a problem if your TCP/IP server is programmed in Node.js anyway:

    const http = require("http");
    http.request("http://localhost:${PORT}/receive", {
      method: "POST",
      headers: {"Content-Type": "text/plain"}
    }).end(data.toString());