2016-05-13 6 views
4

Мое требование немного другое, не знаю, даже если оно достижимо.Node.js - Постоянный адаптер подключения

Я использую Node.js для разработки серверного сервера приложений. Этот сервер в основном выполняет два задания:

(1) Обслуживание клиентов: Мои клиенты - все мобильные телефоны, которые будут отправлять запрос HTTP (S), и после получения ответа закроют сеанс.

(2) Вызов другого асинхронно работающего сервиса: Сервер, с другой стороны, будет подключен к другому серверу, который работает только через соединение TCP/IP, а не с HTTP. Асинхронный означает, что сервер отправит запрос и не должен ждать ответа. Ответ будет получен через одно и то же соединение TCP/IP.

Так поток я хочу достичь, это:

  1. Мобильный телефон отправляет запрос HTTP на сервер
  2. сервер после получения запроса HTTP, делает вызов службы, который находится на TCP/IP
  3. Сервер получает ответ от службы TCP/IP по TCP/IP-соединению
  4. Сервер отвечает на ответ с ответом.

Чтобы представить приведенный выше поток, я добавил следующее изображение.

enter image description here

На изображении выше TCP/IP сервер управляется каким-либо другим провайдером.

Я написал следующий код в node.js, который работает в соответствии с нашим требованием несколько раз, но иногда он отправляет неверный ответ HTTP-запросу. Я не писал код для решения этой проблемы.

var net = require('net'); 

    var client = new net.Socket(); 
    client.connect(2202, 'example_ip', function() { 
    console.log('Connected'); 
    // client.write('Hello, server! Love, Client.'); 
    }); 

    //Lets require/import the HTTP module 
    var http = require('http'); 

    //Lets define a port we want to listen to 
    const PORT = 8080; 

    //We need a function which handles requests and send response 
    function handleRequest(request, response) { 
    var body = ''; 

    request.on('data', function (chunk) { 
     body += chunk; 
    }); 

    request.on('end', function() { 
     console.log('Received request from JMeter------------>>>'); 
     // console.log(body); 
     client.write(body); 

    var count = 0; 
    client.on('data', function (data) { 
      console.log('<<<------------Received from SSM: ' + data); 
      response.end(data); 
      // client.destroy(); // kill client after server's response 
     }); 


    }); 



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

} 

//Create a server 
var server = http.createServer(handleRequest); 

//Lets start our server 
server.listen(PORT, function() { 
    //Callback triggered when server is successfully listening. Hurray! 
    console.log("Server listening on: http://localhost:%s", PORT); 
}); 

Пожалуйста, один из них поможет мне решить эту проблему.

+0

* WebSockets * или * События сервера посланный * бы варианты для этого – Molda

+0

Я думаю, что вы не получили мой вопрос должным образом.Я могу использовать сетевые сокеты на другой стороне, но как я могу обеспечить правильный ответ на правильный запрос с мобильного телефона. Рассмотрите, что mob_1 отправляет запрос серверу, а сервер дает вызов службе tcp. К тому времени другой клиент, который является mob_2, отправляет запрос серверу и снова сервер вызывает службу tcp. К настоящему времени нет входящего сообщения из службы tcp, и оба клиента находятся на удержании. Через некоторое время я получаю входящее сообщение от службы tcp и как сопоставить ответ правильному клиенту? Как продолжить поток, чтобы отправить ответ? – Viddesh

+0

ОК, я вижу. Таким образом, вам нужно только идентифицировать ответ запроса от службы TCP. Поскольку вы не указали какой-либо код в отношении запроса на службу TCP, вам это не поможет. Если служба TCP управляется вами, вы можете запрограммировать ее, чтобы вы могли отправить некоторый идентификатор вместе с запросом, а служба TCP должна вернуть идентификатор, чтобы вы могли легко идентифицировать его. – Molda

ответ

0

Можете ли вы создать экземпляр нового клиента для каждого входящего запроса? Таким образом, соединение TCP для каждого запроса будет уникальным.

0

TCP-потоки не работают как потоки WebSocket (как вы ожидаете). Вы должны использовать свой собственный протокол для связи с сервером TCP. Имейте в виду, что HTTP-клиентов много, и у вас есть только одно TCP-соединение для их обработки, поэтому используйте requestIds, как показано ниже, код сам объясняет.

Не проверено, но вы можете получить эту идею.

shared.js

exports.tcp = { 
    host: 'example_ip', 
    port: 2202 
}; 

exports.http = { 
    host: 'localhost', 
    port: 8080 
}; 

/** 
* TCP "guarantees" that a receiver will receive the reconstituted 
* stream of --> BYTES <-- as it was originally sent by the sender. 
* 
* eg. if written message = 'How are you today?' 
* the messages can come to us as follows: 
*  
*  'How ar' 
*  'e you ' 
*  'today?' 
* 
* so we need to use a simple protocol to handle messages 
*/ 
exports.protocol = protocol; 

function protocol(options) { 

    if (!options) options = {}; 

    this.END_OF_MESSAGE = options.endOfMessage || '\0'; 
    this.END_OF_PART = options.endOfPart || '\1'; 

    this.dataBuffer = ''; 
} 

protocol.prototype.packMessage = function(id, body) { 
    return [id, body].join(this.END_OF_PART) + this.END_OF_MESSAGE; 
}; 

protocol.prototype.unpackMessage = function(message) { 

    var parts = message.toString('utf8').split(this.END_OF_PART); 
    return {id: parts.shift(), body: parts.shift()}; 
}; 

protocol.prototype.extractMessages = function(data, callback) { 

    this.dataBuffer += data.toString('utf8'); 

    if (this.dataBuffer.indexOf(this.END_OF_MESSAGE) !== -1) 
    { 
     var messages = this.dataBuffer.split(this.END_OF_MESSAGE); 
     var incomplete = this.dataBuffer.slice(-1) === this.END_OF_MESSAGE 
      ? '' : messages.pop(); 

     messages.forEach(function(message) 
     { 
      if (message !== '') { 
       callback(this.unpackMessage(message)); 
      } 
     }); 

     this.dataBuffer = incomplete; 
     // rest of 'data' 
    } 

    /** 
    if (Buffer.byteLength(this.dataBuffer, 'utf8') > 10240) { // 10KB 
     console.log('[!] socket flooded'); 
     this.dataBuffer = ''; 
    } 
    */ 
}; 

protocol.prototype.reset = function() { 
    this.dataBuffer = ''; 
}; 

httpServer.js

var http = require('http'); 
var net = require('net'); 

var shared = require('./shared.js'); 
var protocol = new shared.protocol(); 

var server = http.createServer(handleRequest); 
server.listen(shared.http.port, shared.http.host, function() { 
    console.log('HTTP server listening: %s:%s', shared.http.host, shared.http.port); 
}); 

function handleRequest(request, response) { 

    var body = ''; 

    var requestId = nextId++; 
    var eventName = 'message' + requestId; 

    request.on('data', function(chunk) { 
     body += chunk.toString('utf8'); 
    }); 

    request.on('end', function() 
    { 
     // ref#2 
     client.write(protocol.packMessage(requestId, body)); 

     // ref#3 
     client.once(eventName, function(data) { 

      clearTimeout(timeoutId); 
      response.end(data); 
     }); 
    }); 

    var timeoutId = setTimeout(function() { 

     client.removeListener(eventName); 
     response.end('timeout'); 

    }, 10000); // 10 sec. 

    /** 
    * [!] Don't do this; you are adding just another 'data' event to 
    * the TCP client for EVERY http request !? 
    * 
    * request: UNIQUE obj. for every http request 
    * client: a PERSISTENT (TCP) stream obj. 
    * 
    client.on('data', function() { }); 
    **/ 
} 

var client = new net.Socket(); 

// ref#1 
client.connect(shared.tcp.port, shared.tcp.host, function() { 
    console.log('TCP conn. established to: ', shared.tcp.host, shared.tcp.port); 
}); 

var nextId = 0; 
// unique per http req. 

/** 
* [!] Do this (once) (not for every request) 
*/ 
client.on('data', function(data) 
{ 
    protocol.extractMessages(data, function(message) { 

     client.emit('message' + message.id, message.body); 
     // ref#3 
    }); 
}); 

client.on('close', function() 
{ 
    console.log('TCP conn. closed'); 
    client.removeAllListeners(); 
}) 

client.on('error', function() 
{ 
    console.log('TCP conn. error', arguments); 
    // client.destroy(); // and reconnect here 
}); 

tcpServer.js

var net = require('net'); 

var shared = require('./shared.js'); 
var protocol = new shared.protocol(); 

var server = net.createServer(handleConnection); 
server.listen(shared.tcp, function() { 
    console.log('TCP server listening %s:%s', shared.tcp.host, shared.tcp.port); 
}); 

// [!] CONNECTION handler (ref#1) 
function handleConnection(client) 
{ 
    var this.dataBuffer = ''; 

    // [!] DATA handler (ref#2) 
    client.on('data', function(data) { 

     protocol.extractMessages(data, function(message) 
     { 
      var requestId = message.id; 
      var body = message.body; 

      // Do whatever you want with 'body' here 

      /** 
      * And return back to 'client' with 'requestId' using same protocol again 
      * so the 'client' (from httpServer.js) can handle your response 
      */ 
      client.write(protocol.packMessage(requestId, body)); 
     }); 
    }); 
}