2016-03-30 14 views
0

Benim Node sunucumdan Twitter'a bir GET isteği yapmak, yanıt verilerini ayrıştırmak ve bir websocket (ws değil wss) bağlantısı aracılığıyla göndermek istiyorum. Ben ettikSoket kapat: Websocket GET HTTPS isteği Twitter'a ekle API

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 saniye (Ben her zaman 30 +/- 1 saniye var, o zaman), soket bağlantısı kapatırsa, ben aşağıdaki hata yığını aldıktan sonra, dışında - Herşey çalışıyor Twitter'ın genel akışıyla aynı sunucu tasarımını kullanıyor ve iyi çalıştı. Yalnızca, GET uygulamalarının yapılmasında, kapatılmaların gerçekleşmesini talep eder.

Şimdiye kadar, aşağıdaki çözümleri denedim: Waaaay aşağı Heyecan sorgu uri kodlanmış dizede düşük sayım değeri ile

  • azaltma isteği Gelen hızı; Zaman aşımı hala sonra ~ 30 saniye
  • benim GET isteği seçeneklerine bir keepAliveAgent
  • , keepaliveGracePeriod
  • KeepAliveInterval set istek için bir elle yapılmış (hayır npm modülü) ajan denenmiş set, hatta bana geri gönderilen 1 tweet ile ortaya çıkar , soket sunucusundan
  • ve boşuna düğümü'nü newbish şeyler

tümünün bir demet ve dropConnectionOnKeepaliveTimeout. App 30 saniye boyunca güzel çalışıyor; o zaman, o zaman askıda kalıyor.

Sıradaki başlığım: Twitter, yalnızca HTTPS aracılığıyla yalnızca kimliği doğrulanmış isteklerin gönderilmesini gerektirir. Farklı güvenlik seviyesi için kodumda herhangi bir hüküm oluşturmadım. Şimdi bunu takip edeceğim - ve SO topluluğunun herhangi bir fikri olup olmadığını göreceğim. Sunduğunuz herhangi bir yardım büyük beğeni topluyor!

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

Ve burada şunlardır:

// 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(); 
 
    }); 
 
});

Ayrıca

web soket istemci tarafında ben vardır: İşte

çıplak temel soyunmuş kodu var benim sunucu.js adresindeki alaka düzeyi modülleri:

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

cevap

0

Tamam! HTTPS uyumluluğunun kapatmaya neden olmadığı ortaya çıkıyor. Websocket bağlantı mantığını Twitter istek mantığından tamamen ayrıştırdığımda ve çakışmaya alışkın oldukları konsol.log kukla işlevler koyduğumda, Twitter sorgusu iyi çalıştı, ancak websocket bağlantısı bana tam olarak 30'dan az bir süre önce, hangisinin 30 saniye ve bağlantı üzerinden ne kadar veri gönderildiğinden bağımsız olarak.

düzeltme: Manuel (ekstra fazlalık için veya her ikisi) iki birinde, ping/pong tedbirler ayarlanan yolları:

//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') 
    }) 

Yani, sonunda, çok temel bir düzeltme.Bağlantıya neden ihtiyaç duyduğunu anlamıyorum, çünkü Twitter cevabı doğrudan bağlantı üzerinden analiz fonksiyonumdan çıktıktan hemen sonra bağlantıya geçiyor, ~ 1 saniyelik aralıklarla, bağlantıyı son derece aktif tutuyor (ama aşırı yüklenmiyor)). Böyle durumlarda benim asıl sonrası bakın:

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

Muhtemelen, orada hayır 'pong' var, sunucuya geri gönderilen böyle WebSocket bağlantısı, veri dışarı uçan tutar rağmen o varlık olduğunu, öyle bir fikri yok eğer alma ucu hala aktifse. Ama - akış etkinliğim için neden aynı ölçüme ihtiyacım yok? Aynı kanal üzerinden çalışır, akış başladığında istemciden veri almaz ('pong' olmaz) ve ebediyen devam eder (Google geocoding beni kapatır, yani :)).

Sanırım, sonuç olarak, bir akışta varsayılan olarak canlı pong yapma mevcut olmalı ve GET isteğine el ile eklemem gerekiyor, çünkü aslında akış yanıtı için toplu yanıtı donatıyorum. iadeler küçük bir yığın tarafından küçük parçalara ayrılır.

Serin. Her neyse, (veri) çok büyük veri parçaları ile bir GET isteği kullanarak (asmak!) Bir kimse()! Combo çok güzel çalışıyor, bu sorun çözüldü.

+0

Sadece bir kafa doldu: 'npm websocket' kullanıyor ve aynı soruna çalışıyorsanız, bu belgeye göz atın [here] (https://github.com/theturtle32/WebSocket-Node/blob/master /docs/WebSocketServer.md#server-config-options) - ancak verilen varsayılan ayarları almayın. Yukarıda yaptığım şeyi başarmak için, kısa bir aralık ile 'keepalive: true' öğesini manuel olarak ayarlayın. –