Search code examples
javascriptnode.jstcp

How to connect to a TCP server and pass a Javascript to it


I'm definitely a newbie with JS and node. I have telescope management software called SkyX Pro, and it has the ability to run a TCP Server on port 3040. I can connect to it using Netcat and hand it a Javascript starting with //* Javascript *// this works and allows me to startup cameras and other equipment and send commands for taking pictures etc. The issue is it needs to be run from a batch file which makes getting any information back to an HTML page tough (Like Camera, focuser and filter wheel status and temperatures).

The NC call looks like "NC localhost 3040 < Javascript-file.js

To get around the browser to local machine security issues I want to run this from node.js with maybe socket.io-client if possible, but I don't know the proper syntax for it.

I have seen plenty of client syntax sending hello's etc. but nothing send javascript and allowing for two-way connectivity that I can understand.

I have tried using:

var socket = io.connect('http://localhost');`enter code here`
socket.on('httpServer', function (data) {
console.log(data);
document.write(data + "\r\n");
socket.emit('tcp', "For TCP");
});


const net = require('net');
const client = new net.Socket();
client.connect({ port: 3040, host: process.argv[2] });
client.on('data', (data) => {
console.log(data.toString('utf-8'));

But I do not understand it well enough to troubleshoot why it's not working.

Any help would be wonderful, and please treat me like a baby that needs its step by step.

Cheer

Peter


Solution

  • Reading [1], We can assume socket-io isn't the perfect fit for you, because that Server you have sound like a typical tcp-socket server, not a socket.io server ( which requires special headers ) or a web-socket server.

    So you only needs "net" library to do the job.

    const net = require('net');
    
    // module to send a message to TCP-socket server and wait for the response from socket-server
    const sendAndReceive = async (client, message) => {
    
      client.write(message);
    
      let response = null
      await ( new Promise( (resolve, reject) => {
        client.on('data', function(data) {
          response = data;
          resolve()
        });
      }))
    
      return response;
    
    }
    
    // send a single message to the socket-server and print the response
    const sendJSCode = (message) => {
    
      // create socket-client
      const client = new net.Socket();
      client.connect(3040, 'localhost', async function() {
        console.log('Connected');
    
        // send message and receive response
        const response = await sendAndReceive(client, message)
    
        // parse and print repsonse string
        const stringifiedResponse = Buffer.from(response).toString()
        console.log('from server: ', stringifiedResponse)
    
        // clean up connection
        client.destroy()
    
      });
    
    
    }
    
    sendJSCode('var Out; \n Out="TheSky Build=" + Application.build \n\r')
    
    • This script will:

      • Initiate a socket client
      • on connection successfully, client sends a message
      • client receives back response from that message
      • client prints response to terminal
    • Note that TheSkyX has a limitation of 4096 bytes for each message[2], any more than that and we will need to chunk the message. So you may want to keep the js-code short and precise.

    • that snippet I gave is minimal, it doesn't handle errors from server. If you want, you can add client.on("error", .. ) to handle it.

    • Your point of connecting to the socket server directly from browser is very intriguing, unfortunately it is not allowed by modern browsers natively due to security concerns 3

    [1] https://socket.io/docs/#What-Socket-IO-is-not:~:text=That%20is%20why%20a%20WebSocket%20client,to%20a%20plain%20WebSocket%20server%20either.

    [2] https://www.bisque.com/wp-content/scripttheskyx/scriptOverSocket.html#MSearchField:~:text=set%20to%204096%20bytes