【问题标题】:How to make client talk to server in same node proccess?如何让客户端在同一节点进程中与服务器通信?
【发布时间】:2013-07-17 15:11:26
【问题描述】:

我有一个用 SSJS (Node) 编写的应用程序......这个应用程序需要向 fsockopen 请求的 php 脚本提供数据......好吧......这个服务器需要从第二个服务器收集数据持久连接。这该怎么做?使相同的过程协调这些连接?这可能吗?

var net         = require('net');
/*  #############################################
    #  "CLIENT" Used to connect to data server
    #   --------------------------------- 
    #############################################
*/

var clientConnect   = net.createConnection(port, host);
clientConnect.setEncoding('utf8');

clientConnect.on('connect', function () {
    console.log('Client','Connected to CAGEAPI');
    clientConnect.write('user@pass');
});

clientConnectt.on('data', function (data) {
    console.log('Client','Data received: ' + data);
});

clientConnect.on('close', function(code) {
    console.log('Client','Connection closed');
});

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


/*  ################################################
    #                                
    #  "SERVER" Used to serv data to PHPScripts 
    #   --------------------------------        
    ################################################
*/
var handleServer = net.createServer(function(server) {
    console.log('Server','CONNECTED: ' + server.remoteAddress +':'+ server.remotePort);
    server.on('data', function(data) {

        console.log('Server','DATA ' + server.remoteAddress + ': ' + data);
        // Write the data back to the socket, the client will receive it as data from the server
        server.write('You said "' + data + '"');

    });

    // Add a 'close' event handler to this instance of socket
    server.on('close', function(data) {
        console.log('Server','CLOSED: ' + server.remoteAddress +' '+ server.remotePort);
    });

}).listen(port2, host2);

(客户端和服务器)都工作正常......但是如何让他们互相交谈?

【问题讨论】:

  • 您需要将客户端创建代码移动到服务器的connection 事件处理程序(您传递给net.createServer() 的函数),并使用.pipe() 将两个对等点的流连接在一起- 如果您想充当代理,直接在对等方之间启用全双工通信,而不需要 Node 的其他参与,则需要在两个方向上执行此操作。然而,有人认为这可能是一个不必要的复杂问题——你不能直接从 PHP 连接到远程主机吗?还是我错过了什么/
  • 关于您的评论...我无法直接连接,因为数据服务器需要持久连接处理程序...他们不允许通过同一 IP 进行多个连接..
  • 他们要求我制作一个 Python 或 C++ 应用程序来处理这种情况......但我会尝试用 js 来制作它
  • 您希望如何在多个 PHP 客户端之间分配数据? PHP客户端会连接,检索自上次客户端连接后的所有数据然后消失吗?或者您是否希望将相同数据从数据源分发到多个客户端?
  • 是的.. PHP 连接获取数据然后断开连接

标签: php javascript node.js


【解决方案1】:

我想你可能会追求这样的东西:

/*jslint node: true, white: true */

// Declare constructors
var DataSource, PHPClientServer;

// The DataSource class
// Handles connecting/reconnecting to the data source, and piping endpoints together
(function() {
    "use strict";

    DataSource = function(net)
    {
        this.net = net;
    };

    DataSource.prototype.net = null;

    DataSource.prototype.host = 'localhost';
    DataSource.prototype.port = 0;
    DataSource.prototype.user = '';
    DataSource.prototype.pass = '';

    DataSource.prototype.socket = null;
    DataSource.prototype.currentClient = null;

    DataSource.prototype.start = function(host, port, user, pass)
    {
        if (host !== undefined) {
            this.host = host;
        }
        if (port !== undefined) {
            this.port = port;
        }
        if (user !== undefined) {
            this.user = user;
        }
        if (pass !== undefined) {
            this.pass = pass;
        }

        this.socket = this.net.createConnection(this.port, this.host);

        this.socket.on('connect', function () {
            console.log('Data source connected');

            this.socket.write(this.user + '@' + this.pass);
        }.bind(this));

        this.socket.on('error', function() {
            console.error('Error on data source connection');

            this.stop();
            this.start();
        }.bind(this));

        this.socket.on('end', function() {
            console.error('Data source connection terminated');

            this.stop();
            this.start();
        }.bind(this));
    };

    DataSource.prototype.stop = function()
    {
        this.socket.end();
        this.socket = null;
    };

    DataSource.prototype.attachClient = function(client)
    {
        console.log('Attaching client to data source');

        this.currentClient = client;

        this.socket.pipe(this.currentClient);
        this.currentClient.pipe(this.socket, {end: false});
    };

    DataSource.prototype.detachCurrentClient = function()
    {
        console.log('Detaching client from data source');

        this.socket.unpipe(this.currentClient);
        this.currentClient.unpipe(this.socket);

        this.currentClient = null;
    };

    DataSource.prototype.hasClient = function()
    {
        return this.currentClient !== null;
    };
}());

// The PHPClientServer class
// Handles the server operations for PHP clients
(function() {
    "use strict";

    PHPClientServer = function(net, dataSource)
    {
        this.net = net;
        this.dataSource = dataSource;

        this.pendingClientStack = [];
    };

    PHPClientServer.prototype.net = null;
    PHPClientServer.prototype.dataSource = null;

    PHPClientServer.prototype.host = null;
    PHPClientServer.prototype.port = null;

    PHPClientServer.prototype.server = null;
    PHPClientServer.prototype.pendingClientStack = null;

    PHPClientServer.prototype.start = function(host, port)
    {
        var clientTerminateHandler = function() {
            console.log('Client disconnected');
            this.dataSource.detachCurrentClient();

            if (this.pendingClientStack.length) {
                console.log('Attaching next client in queue');
                this.dataSource.attachClient(this.pendingClientStack.shift());
            }
        }.bind(this);

        if (host !== undefined) {
            this.host = host;
        }
        if (port !== undefined) {
            this.port = port;
        }

        this.server = this.net.createServer(function(client) {
            console.log('Client connected');

            client.on('end', clientTerminateHandler);
            client.on('error', clientTerminateHandler);

            if (this.dataSource.hasClient()) {
                console.log('Client added to queue');
                this.pendingClientStack.push(client);
            } else {
                this.dataSource.attachClient(client);
            }
        }.bind(this));

        this.server.listen(this.port, this.host);
    };

    PHPClientServer.prototype.stop = function()
    {
        this.server.close();
        this.server = null;
    };
}());

// Bootstrap
var net, dataSource, server;

net = require('net');

dataSource = new DataSource(net);
dataSource.start('192.168.0.1', 23);

server = new PHPClientServer(net, dataSource);
server.start('0.0.0.0', 12345);

我意识到这是一堵代码墙,几乎没有解释,所以请询问是否有什么你不明白的地方。

另外,在任何人说之前,是的,我完全意识到我正在将一种原型 OOP 语言视为一种经典语言,Javascript!= Java,yada yada yada。我不在乎,我喜欢以这种方式使用 Javascript。

【讨论】:

  • Man...beautyfull 代码!非常好的代码...它没有工作..返回很多关于递归事物的警告...然后最大堆栈超出...但我正在尝试修复它...顺便说一句...我不需要存储的数据因为数据永远不会相同
  • .bind(this) 有什么作用?
  • @FilipeTagliacozzi 我在离开办公室前不久写了这篇文章,在回家的路上我正在考虑它,我意识到这可能不是你想要做的。稍后我将对其进行重写,并将其更新为我认为您真正想要的内容(这次也进行测试)。 .bind(this) 确保回调始终在正确的上下文中执行。另一种方法是var that = this;。对于一个本来就不应该存在的问题,两者都是丑陋的解决方案。
  • 好的...我会尝试更好地解释:我需要一个通过 TCP/IP 持久连接到数据服务器(B)的服务(A)。同时创建一个服务器(C),在数据服务器(B)和 PHP 客户端(X,Y,Z)之间形成一个桥梁......所以这些客户端可以通过服务请求传递一些参数的数据( A)到服务器(B)然后将数据返回给客户端(X,Y,Z)......等待您的建议
  • @FilipeTagliacozzi 当您说 PHP 客户端将参数传递给数据服务器时,它们究竟是如何做到的?这里真正的问题是,如果多个客户端都需要提取不同的数据,那么单个持久连接很难在多个客户端之间共享。如果他们都需要相同的数据,那么简单的“广播”类型配置很容易,但如果他们需要不同的数据,那么一次只有其中一个可以访问服务 - 因为连接一次只能做一件事
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-21
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多