I am writing an application on node.js, which is both an http and tcp server. tcl server works with certain clients - sends them commands and gets a response.

Necessary: ​​When you receive a request via http - send a command to a specific client, receive a response from it and give this response in the request via http. All this needs to be done without blocking, i.e. to support the work of several clients via http and using several tcp clients.

//http server http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); }).listen(8888); //tcp server var clients = []; net.createServer(function (socket) { socket.name = socket.remoteAddress + ":" + socket.remotePort clients.push(socket); socket.on('data', function (data) {}); socket.on('error',function(error) { socket.end(); console.log(error); }); socket.on('close',function(had_error) {}); socket.on('end', function () {console.log('onend');}); }).listen(5000); 

Those. you need to somehow send the response object http to socket.on ('data', function (data) {}); where reading from the client's tcp socket occurs.

Any ideas on how to do this or some kind of architectural solution?

Thanks in advance for your reply.

Addition:

I have to additionally read the information from tcp clients and they are authorized on the server. And only when I send them a command then I wait for an answer right away

  socket.on('data', function (data) { var imei = data.toString("binary"); //авторизация if (imei == 'xxxxxxxx') { var raw = '01'; this.imei = imei; var now = new Date(); var buff = new Buffer(raw, 'hex'); socket.write(buff); } //клиент уже прошело авторизацию. шлет нам какие-то данные } else if(this.imei && (data.length == 3 || data.length == 6)) { } else if (data[0] == 4 && data[2] > 0) { } else if (this.imei && data.length > 3) { //и где-то здесь нужно нам, наверное, поймать ответ от клиента после посылки ему команды }); 
  • can be more precise about "send a command to a specific client", by what criteria is it selected? - Pifagorych
  • in the request from http comes the client id tcp. Types "send a command to such a tcp client - wait for an answer and give this answer via http" - programmer

1 answer 1

 //http server http.createServer(function(request, response) { var sock_id = request. // достаете id сокета process(responce, sock_id); // и передаете в функцию }).listen(8888); //tcp server var clients = {}; // лучше использовать объект для ассоциативной связи id и сокета net.createServer(function (socket) { socket.name = socket.remoteAddress + ":" + socket.remotePort; var id = ... // формируете id можно id = socket.name; clients[id] = socket; socket.on('error',function(error) { delete clients[socket]; socket.end(); console.log(error); }); socket.on('close',function(had_error) {}); socket.on('end', function () {console.log('onend');}); }).listen(5000); function process(responce, sock_id) { var sock = clients[sock_id]; sock.once('data', onData); // это событие обработается единожды sock.write(''); // отправляете свою команду команду function onData(data) { response.writeHead(200, {"Content-Type": "text/plain"}); response.end(data.toString()); } } 

Something like that, wrote without a node.

Updated:

 var clients = {}; var request_queue = []; var current_response = {}; http.createServer(function(request, response) { // создаете свой запрос и заносите различные данные // такие как id сокета, команда и прочее var req = { response: responce, sock_id: ..., cmd: ... }; // заносите его в очередь request_queue.unshift(req); // если очередь пустая (или первый запрос) выполняем его if (!request_queue.length) { next_request(); } }).listen(8888); net.createServer(function (socket) { clients[sock_id] = socket; socket.on('data', function(data) { // проверяем авторизован ли сокет, нет - авторизуем if (!socket.imei) { auth(socket, data); return; } //клиент уже прошел авторизацию. шлет нам какие-то данные // тут их обрабатываете, и там где данные являются ответом, выполняете опр. действия if(data.length == 3 || data.length == 6) { return; } if (data[0] == 4 && data[2] > 0) { return } if (data.length > 3) { // например, тут // обрабатываете current_response.writeHead(200, {"Content-Type": "text/plain"}); current_response.write(data); // и переходите к следующему запросу next_request(); return; } }); // все ошибки и таймауты обрабатываете сами }).listen(5000); function auth(sock, data) { var imei = data.toString("binary"); if (imei != 'xxxxxxxx') return sock.write(/*error_code*/); sock.imei = imei; var raw = '01'; var buf = new Buffer(raw, 'hex'); socket.write(buf); } function next_request() { // достаем данные запроса из очереди var req = request_queue.pop(); var sock = clients[req.sock_id]; current_response = req.response; sock.on('data', onData); sock.write(req.cmd); } 

I didn’t check the performance, but I think the idea is clear, sawing by itself, identification of sockets and so on.

  • OK. thank. And if I still need to additionally listen on tcp that customers send. Since the tcp-client passes authorization and sends other information. and only when I send a command on tcp - then wait for the client's response from this tcp and give on htpp, otherwise listen to another info from the client and do something there. - Programmer
  • @programmer, two clarifying questions: at the time of sending the command and getting the result, does tcp socket send any other data that is not intended for the http client making the request? There may be a situation where, in a short period of time, several requests were made from different clients to the same tcp socket in order 1, 2, 3, due to various network delays and data processing, the results came in a chaotic order (2 , 13)? - Pifagorych
  • from http clients need to create a queue. those. one tcp client executes commands only sequentially. those. http clients wait when the queue reaches them while a command is being executed on this tcp socket from another http client. Well or http clients should fall off by timeout if it’s been over for example more than 1 minute as they connect to the server and wait (i.e. have not received an answer yet from the client's tcp or the line has not reached them yet to send the command) Ie the tcp socket command is not sent until the tcp client responds to the previous command or if it does not respond for a long time or disconnects. - Programmer
  • but the tcp socket can still send other information. regardless of whether they sent him commands or not. Those. when we wait for the response from the socket to the command - you need to check this response to the command or other information. This is easily verified. when it answers, it transmits some numbers, and when it simply sends information, then others. Those. while waiting for a response, other information may come in that need to be ignored and wait for a response. - Programmer
  • @programmer, updated - Pifagorych