2013-07-17 44 views
0

我有一個用SSJS(Node)編寫的應用程序......這個應用程序需要向php腳本提供數據,這個腳本將會被fsockopen請求..這裏就...這個服務器需要通過一個第二服務器來收集數據持續連接。這個怎麼做?讓相同的過程協調這些連接?這可能嗎?如何使客戶端在同一節點進程中與服務器通話?

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('[email protected]'); 
}); 

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); 

這兩個(客戶端和服務器)工作正常......但如何讓他們互相交談?

+1

您需要將客戶端創建代碼移動到服務器的'connection'事件處理函數(您傳遞給'net.createServer()'的函數),並使用'.pipe( )' - 如果你想充當代理,直接在對等節點之間進行全雙工通信,而無需其他節點參與,則需要在兩個方向上執行此操作。然而,想到這可能是一個不必要的複雜 - 你不能直接從PHP連接到遠程主機?或者我錯過了什麼/ – DaveRandom

+0

發表評論...我無法直接連接,因爲數據服務器需要持久連接處理程序...他們不允許通過同一IP連接多個連接.. –

+0

他們要求我製作Python或C++應用程序來處理這種情況...但我試圖用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。

+0

曼...美麗的代碼!非常好的代碼...它沒有工作..迴歸很多遞歸事件的警告...然後最大堆棧超過...但我試圖修復它...順便說一句...我不需要存儲數據結果數據永遠不會相同 –

+0

什麼.bind(這)? –

+0

@FilipeTagliacozzi在我離開辦公室之前不久,我在回家的路上寫下了這篇文章,我意識到這可能不是您想要做的。我稍後將重寫它,並將其更新爲我認爲您實際需要的內容(並在此次進行測試)。 ['.bind(this)'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)確保回調始終在正確的上下文中執行。另一種方法是'var that = this;'。對於一個本來不應該存在的問題,這兩者都是醜陋的解決方案。 – DaveRandom

相關問題