2016-03-30 5 views
0

GETリクエストを自分のノードサーバーからTwitterに送信し、応答データを解析してwebsocket(ws、wssではない)接続経由で送信します。私がしましたソケットがハングアップ:Websocket Twitter APIへのHTTPSリクエストを受け取ります

Error: socket hang up 
    at createHangUpError (_http_client.js:200:15) 
    at TLSSocket.socketOnEnd (_http_client.js:292:23) 
    at emitNone (events.js:72:20) 
    at TLSSocket.emit (events.js:166:7) 
    at endReadableNT (_stream_readable.js:905:12) 
    at nextTickCallbackWith2Args (node.js:442:9) 
    at process._tickCallback (node.js:356:17) 

:30秒(私はそれが常に30 +/- 1秒だが、それを時限)、ソケット接続がハングアップして、私は次のエラー・スタックを取得した後、ことを除いて - すべてが働いていますTwitterの公開ストリームで同じサーバーデザインを使用していて、うまくいきました。ハングアップが発生したことをGET要求で実装した場合のみです。

はこれまでのところ、私は次の解決策を試してみた:

  • は、TwitterのクエリURIエンコードされた文字列で、低カウント値とメーリングリストのダウン要求の着信率を絞ります。タイムアウトは〜30秒
  • は私のGETリクエストのオプションにkeepAliveAgent
  • KeepAliveIntervalkeepaliveGracePeriodを設定要求のため、手動で構築された(なしnpmモジュール)薬を試しセットまだ後、でも私に戻って送信され1件のつぶやきで発生します、ソケットサーバ
  • と無駄にノードnewbishもの

すべての束に とdropConnectionOnKeepaliveTimeout。アプリは30秒間美しく動作し続けます。その後、ハングアップします。

私の次のリード:Twitterでは、HTTPS経由でアプリケーションのみの認証済みリクエストを送信する必要があります。私は、異なるセキュリティレベルのために自分のコードに規定を設けていません。私は今それをフォローアップして、SOのコミュニティに何か考えがあるかどうかを確認します。あなたが提供できるどんな助けも大変に感謝しています!ここで

は必需品を露出するためにストリップダウンコードは、です:

// Initialize basic server for the web socket requests 
 
var handShakeServer = http.createServer(function(request, response) { 
 
    console.log((new Date()) + ' Received request for ' + request.url); 
 
    response.writeHead(404); 
 
    response.end(); 
 
}); 
 

 
handShakeServer.listen(8080, function() { 
 
    console.log((new Date()) + ' Socket server is listening on port 8080'); 
 
}); 
 

 
// Initialize the socket server itself. 
 
var socketServer = new WebSocketServer({ 
 
    httpServer: handShakeServer, 
 
    autoAcceptConnections: false, 
 
    keepAliveInterval: (3600 * 1000), 
 
    dropConnectionOnKeepaliveTimeout: false 
 
}); 
 

 
// On request, listen for messages. 
 
socketServer.on('request', function(request) { 
 
    
 
    // Initialize connection from verified origin 
 
    var connection = request.accept('echo-protocol', request.origin); 
 
    
 
    // On message (search params from client), query Twitter. 
 
    connection.on('message', function(message) { 
 
    
 
    // BEARER_ACCESS_TOKEN is for Twitter's application-only authentication 
 
    var options = { 
 
     'path': '/1.1/search/tweets.json?q=stuff', 
 
     'hostname': 'api.twitter.com', 
 
     'method': 'GET', 
 
     'headers': { 
 
     'Authorization': ('Bearer ' + process.env.BEARER_ACCESS_TOKEN), 
 
     'Accept': '*/*' 
 
     }, 
 
     'agent': agent, 
 
     'port': 443, 
 
    }; 
 
    
 
    // Query twitter via HTTPS GET, listen for response 
 
    var req = new https.request(options, function(res) { 
 
     var responseString = ''; 
 

 
     // On data, concatenate the chunks into a whole JSON object 
 
     res.on('data', function(tweet) { 
 
     responseString += tweet; 
 
     }); 
 
     
 
     // On completion of request, send data to be analyzed. 
 
     res.on('end', function() { 
 

 
     // Once returned, send data to client through socket connection. 
 
     var result = doSomeAnalysis(JSON.parse(responseString)); 
 
     connection.sendUTF(JSON.stringify(result)); 
 

 
     }); 
 
    }); 
 

 
    // The https request is done; terminate it. 
 
    req.end(); 
 
    }); 
 
});

はまた、ウェブソケットクライアント側では、私が持っている:

client.connect('ws://localhost:8080/', 'echo-protocol', 'twitterQuery'); 

そして、ここでは、私のserver.jsの関連モジュール:

var util    = require('util'); 
var https   = require('https'); 
var http    = require('http'); 
var WebSocketServer = require('websocket').server; 
var HttpsAgent  = require('agentkeepalive').HttpsAgent; 

答えて

0

HTTPSとの互換性がハングアップを引き起こしていないことがわかります。 Twitterのリクエストロジックからwebsocket接続ロジックを完全に切り離し、重複していたconsole.logダミー関数を置くと、Twitterクエリはうまくいきましたが、websocket接続によってまったく同じようにハングアップエラーが発生しました接続にどれくらいのデータが送信されたかにかかわらず、いつでも使用できます。

修正:手動(余分な冗長性を確保するため、またはその両方)の二つのうちの一つには、ping /卓球対策で設定方法:

//SERVER SIDE: 

    // Option 1: Use the npm module's event 'ping' 
    connection.on('ping', function(data){ 
     console.log('Server: ping received at: ' + (new Date()))   
    }) 

    // Option 2: Use the more generalized event 'message', look for your 
    // custom 'ping' message 
    connection.on('message', function(message){ 
     console.log("Socket server received message from client.") 
     if (message.utf8Data == 'ping'){ 
      console.log('pong!') 
     } 
    }) 

//CLIENT SIDE: 
    setInterval(function(){    
     if (connection.connected){ 
      // To match Option 1 above, use this: 
      connection.ping(); 
      // To match Option 2 above, use this: 
      connection.sendUTF('ping'); 
     } 
    }, 19900) 

    connection.on('pong', function(){ 
     console.log('Client: pong received at: ' + (new Date()) + '\n') 
    }) 

だから、最終的には、非常に基本的な修正。私は、Twitterのレスポンスが〜1秒間隔で分析機能を終了した直後に接続を介して直接パイプされているので、コネクションを非常にアクティブに保つ(ただし過負荷にならないように) )。この問題が発生した場所のための私の元の記事を参照してください:

// Once returned, send data to client through socket connection. 
var result = doSomeAnalysis(JSON.parse(responseString)); 
connection.sendUTF(JSON.stringify(result)); 

おそらく、それはそれはないアイデアを持っていないなど、WebSocketの接続が飛び出し、そのデータを保持していても、あること、背中サーバーに送信されているNO「ピンポン」はありませんということですそれの受信側がまだアクティブである場合。しかし、私のストリーミング活動のために、同じ対策が必要なのはなぜですか?それは同じチャンネルを介して動作し、ストリーミングが開始されるとクライアントからデータを受け取ることなく(「ポン」なし)、永続的に(Googleのジオコーディングが私を止めるまで、:))続けます。

推測では、デフォルトではストリーム内にいくつかのキープアライブポンギングが存在している必要があります。私は基本的にバッチ応答をストリームアウトするためにGET要求に手動で追加する必要があります、小さなチャンクで小さなチャンク、戻り値が私の分析機能を終了するように。

クールです。とにかく、大きなデータのチャンクでGETリクエストを使用して、誰かがハングアップしている場合に備えて、この(長すぎる)ポストを残しておき、ウェブソケット接続を通してそれらをストリーミングすることを考えました。コンボはうまく機能し、この問題は解決されました。

+0

「npm websocket」を使用していて、同じ問題が発生している場合は、この文書[こちら](https://github.com/theturtle32/WebSocket-Node/blob/master)を参照してください。 /docs/WebSocketServer.md#server-config-options) - ただし、デフォルトの設定は当てにしないでください。上に行ったのと同じことを達成するために、短い間隔で手動で「keepalive:true」を設定します。 –

関連する問題