简体   繁体   中英

Node.Js Async task via serial port

I'm communicating with a controller via Serial port (npm serialport module).

The controller handles multiple elements by their id.

The communication is аsync (I sent a request, and there is an event "serialport .on('data')..." that received the response prom the controller.

I have a web API (GET) that receives an id and send a request to the controller to receive the status of element with the given id.

The problem is that when the API needs to response, i haven't received the data from the controller yet.

I also need to support multiple requests at a time via the API.

How do i manage to respond to every request with its correct response?

Thanks a lot Avi

Put controller code in its own module and use a queue of commands. As you pull the next command make that the 'current command'. Each command has a process() function that handles the data from the serial port and returns a value indicating whether it expects more data or has completed. If a command completes then pull the next command.

Each command has a callback that it calls when it completes which you can use to return the async response.

The following is an untested outline (ES6):

// controller.js

var cmds = [], currentCmd = null;                
var stream = null;                               

class ControllerCommand {                        
  constructor(strm) { this.stream = strm;}       
  send(data) {this.stream.write(data);}          
}                                                
class StatusCmd extends ControllerCmd {          
  constructor(stream, id, cb) {                  
    super(stream)                                
    this.id = id;                                
    this.cb = cb                                 
  }                                              
  exec() { this.send(`STATUS ${id}`);}           
  parse(resp) {                                  
    this.status = resp;                          
    this.cb(this.status);                             
    return true;                                 
  }                                              
}                                                
function next() {                                
  if (cmds.length > 0) {                         
    currentCmd = cmds.shift();                   
    cmd.exec();                                  
  }                                              
}                                                
function add(cmd) {                              
  cmds.push(cmd);                                
  if (cmds.length == 1) next();                  
}                                                
export function status(id, cb) {                 
  add(new StatusCmd(stream, id, cb));            
}                                                
export function init(str) {                      
  stream = str;                                  
  stream.on('data', (data) => {                  
    if (currentCmd.parse(data.toString())) {     
      next();                                    
    }                                            
  });                                            
}                                                

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