简体   繁体   中英

Node.js TCP write multiple commands

I am connecting to a serial device over the internet, using an ethernet to serial device. I am communicating with it via a small node.js app. The following code gets back the information I need:

var net = require('net');

var zone1 = 'AgABBgAJ';
var zone2 = 'AgACBgAK';
var zone3 = 'AgACBfAZ';
var zone4 = 'AgACBaAW';
var zone5 = 'AgACBsAV';

var client = new net.Socket();
client.connect(10006, '10.0.1.217', function() {
    console.log('Connected');
    client.write(Buffer.from(zone1, 'base64').toString('ascii')+'\n');

});

client.on('data', function(data) {
    var data_array = new Uint8Array(data);
    console.log(data_array);
    var decoded = [];
    decoded['zone'] = data_array[16];
    decoded['power'] = data_array[18] == 128 ? 'On' : data_array[18] == 0 ? 'Off' : data_array[18] == 192 ? 'Muted' : 'Unknown';
    decoded['input'] = data_array[22] + 1;
    decoded['vol'] = data_array[23] - 196;
    decoded['mute'] = data_array[18] == 192 ? 'On' : 'Off';
    decoded['state'] = (data_array[18] == 128) || (data_array[18] == 192) ? true : false;

    console.log('-- Zone: ' + decoded['zone']);
    console.log('-- Power: ' + decoded['power']);
    console.log('-- Input: ' + decoded['input']);
    console.log('-- Volume: ' + decoded['vol']);
    console.log('-- Mute: ' + decoded['mute']);

    client.destroy(); // kill client after server's response
});

client.on('close', function() {
    console.log('Connection closed');
});

What I need to do now is write the other commands (zone2,zone3,zone4,zone5) and get the data back from them as well.

Is there a way to loop through an array of commands and output the data after each command?

Thanks!

EDIT: Here is the output from the app

Connected
Uint8Array [
  2, 0, 0,   6, 0, 63, 0,   0,
  0, 0, 0,   0, 0, 71, 2,   0,
  1, 5, 0,   0, 0,  0, 0, 222,
  8, 8, 0, 246
]
-- Zone: 1
-- Power: Off
-- Input: 1
-- Volume: 26
-- Mute: Off
Connection closed

I would use an Array or Set for your zones.

const zones = [
  'AgABBgAJ',
  'AgACBgAK',
  'AgACBfAZ',
  'AgACBaAW',
  'AgACBsAV'
];

Then, you can loop through easily:

for (const zone of zones) {
  client.write(Buffer.from(zone, 'base64').toString('ascii') + '\n');
  // etc.
}

However, there's probably more you need to do here. I would recommend building out a small client class that can wrap up your commands and status retrieval. I assume you want to get a response before querying the next zone, rather than fire-and-forget. Check out async/await .

You can create yourself a little state machine where you put the zones in an array and keep a variable that points to the next index in that array to process. Then, after you finish processing the data event for a zone, you send the command for the next zone until you have no more items in the array.

const net = require('net');

const zones = [
    'AgABBgAJ',
    'AgACBgAK',
    'AgACBfAZ',
    'AgACBaAW',
    'AgACBsAV'
];

let zoneIndex = 0;
const client = new net.Socket();

function sendNextZone() {
    if (zoneIndex < zones.length) {
        client.write(Buffer.from(zones[zoneIndex++], 'base64').toString('ascii')+'\n');
    } else {
        // no more zones to send,  so we're done
        client.destroy();
    }
}


client.connect(10006, '10.0.1.217', function() {
    console.log('Connected');
    sendNextZone();    
});

client.on('data', function(data) {
    let data_array = new Uint8Array(data);
    console.log(data_array);
    let decoded = [];
    decoded['zone'] = data_array[16];
    decoded['power'] = data_array[18] == 128 ? 'On' : data_array[18] == 0 ? 'Off' : data_array[18] == 192 ? 'Muted' : 'Unknown';
    decoded['input'] = data_array[22] + 1;
    decoded['vol'] = data_array[23] - 196;
    decoded['mute'] = data_array[18] == 192 ? 'On' : 'Off';
    decoded['state'] = (data_array[18] == 128) || (data_array[18] == 192) ? true : false;

    console.log('-- Zone: ' + decoded['zone']);
    console.log('-- Power: ' + decoded['power']);
    console.log('-- Input: ' + decoded['input']);
    console.log('-- Volume: ' + decoded['vol']);
    console.log('-- Mute: ' + decoded['mute']);

    // done processing this zone, send the command for the next one
    sendNextZone();
});

client.on('close', function() {
    console.log('Connection closed');
});

client.on('error', function(err) {
    console.log(err);
});

Note: There is no complete guarantee with a TCP socket that you will get all the data you want in one data event - it is possible, particularly with larger data sets or slower networks that the data might be split between multiple data events. If that were the case, you would need a buffer so you could buffer data until you had a "full" set of data that you could then process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM