2015-10-07 54 views
0

我是websockets的新手。NodeJS:如何使用訂閱websocket的多個響應來更新視圖?

我想在一個MeanJS應用程序中實現一個websocket來訂閱另一個網站提供的一些實時數據,當數據得到返回時我想更新我的視圖中的表與結果。

我遇到了一個邏輯問題。

throw new Error('Cant set headers after they are sent.'); 

我明白爲什麼這個錯誤是發生,但作爲新的WebSockets和相當新:我的執行失敗,因爲它試圖在一個TCP連接(我相信)發送多個響應,它與錯誤死亡到NodeJS我不知道如何以有意義的方式重構此代碼。

在我的客戶方控制器:

// Get Orderbook 
    $scope.getOrderbook = function() { 
     $http.get('exchanges/' + $stateParams.exchangeId + '/get_orderbook') 
      .success(function(data) { 
       console.log("ORDERBOOK DATA: " + data); // DEBUGGING 
       $scope.orderBook = data; 
      }); 
    }; 

在我的服務器端控制器:

exports.getOrderbook = function(req, res, next) { 
     var exchange = req.exchange; 

     if(exchange.slug === 'somesite') { 
      var ws = new WebSocket('wss://www.somesite.com/realtimews'); 

      ws.on('open', function open() { 
       ws.send('{"op": "subscribe", "args": "orderBook"}'); 
      }); 

      ws.on('message', function(message) { 
       var response = JSON.parse(message); 

       if(response.table) { 
        res.jsonp(response.data); 
       } 
      }); 
     } 
    }; 

什麼是重構這個代碼,這樣我可以訂閱的WebSocket的最佳方式,接收來自它的消息,以及何時收到消息,用數據更新視圖?

回答

0

在每個新的傳入http請求上,您都試圖打開一個新的websocket到某個站點,然後每次您收到一條消息時您都試圖發送響應。同時,你永遠不會關閉你的websocket。

當第一個響應已發送時,當您嘗試向同一http請求發送第二個http響應時,會發生特定錯誤。當你在websocket上得到第二條消息時,這將發生在你的代碼中。

另外,你每次打開一個新的websocket時,你只會讓這些打開的websocket累積起來。

如果您確實需要使用websocket來獲取您的數據,那麼只要您收到第一條消息或刪除與特定請求關聯的事件處理程序,就需要關閉websocket。

下面是做這件事:

exports.getOrderbook = function(req, res, next) { 
    var exchange = req.exchange; 

    if(exchange.slug === 'somesite') { 
     var ws = new WebSocket('wss://www.somesite.com/realtimews'); 

     ws.on('open', function open() { 
      ws.send('{"op": "subscribe", "args": "orderBook"}'); 
     }); 

     ws.on('message', function(message) { 
      var response = JSON.parse(message); 

      if(response.table) { 
       res.jsonp(response.data); 
      } else { 
       res.jsonp(/* some error response here */) 
      } 
      // close the websocket so we don't associate any more responses 
      // with this particular http request 
      ws.close();     
     }); 
    } else { 
     // need to send some response here 
    } 
}; 
+0

謝謝!我知道錯誤發生的原因,但我錯過了ws.close()。 如果我這樣實現它,在返回響應之後關閉websocket,我將不得不不斷髮送HTTP請求來調用我的服務器端函數以在初始響應之後獲取更新。 這種不符合訂閱websocket以獲取數據而不是執行長輪詢的目的,我試圖避免 –

+0

@DaveRich - 如果需要,您可以創建一個webSocket並存儲全局套接字引用。但爲了將這些信息返回給客戶端,您需要持久連接到客戶端(例如客戶端和服務器之間的websocket)。您沒有真正解釋您嘗試解決問題的總體背景和體系結構,因此我不確定推薦的內容。也許你應該做的是讓每個客戶端都直接連接一個websocket到訂單本服務器,這樣它就可以從那裏獲得實時信息? – jfriend00

+1

@DaveRich - 或者,你可以有一個websocket連接到你的服務器的實時源,並讓每個客戶端連接一個websocket到你的服務器。然後,只要您在服務器上收到實時信息,就可以立即將適當的數據轉發給任何連接的客戶端。 – jfriend00