我的要求有点不同,即使它是可以实现的也不知道。
我使用Node.js开发后端应用服务器。这个服务器基本上做两个工作:
(1)为客户提供服务:我的客户都是将发送HTTP(S)请求的手机,收到回复后会关闭会话。
(2)调用其他异步工作服务:另一方面,服务器将连接到仅通过TCP / IP连接而非HTTP工作的其他服务器。这里异步意味着,服务器将发送请求,不应等待响应。响应将通过相同的TCP / IP连接接收。
所以我想要实现的流程是:
为了表示上述流程,我附上了以下图片。
在上图中,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 :(得分:0)
您可以为每个传入请求实例化一个新客户端吗?这样,每个请求的TCP连接都是唯一的。
答案 1 :(得分: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) );
});
});
}