Ich möchte eine Anfrage von meinem Node-Server an Twitter, analysieren Sie die Antwortdaten, und senden Sie es über eine websocket
(Ws, nicht WSS) Verbindung. Alles funktioniert - außer, dass, nach 30 Sekunden (I timed es, es ist immer 30 +/- 1 Sekunden), die Socket-Verbindung auflegt, und ich erhalte die folgende Fehlerstack:Socket auflegen: Websocket GET HTTPS Anfrage an Twitter 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)
Ich habe benutze das gleiche Serverdesign mit dem öffentlichen Stream von Twitter und es hat gut funktioniert. Nur wenn die Anforderung GET
implementiert wird, treten die Hangups auf.
Bisher hat ich folgende Lösungen versucht:
- Drosselung Anfrage eingehende Rate waaaay nach unten mit einem niedrigen Zählwert in der Twitter-Abfrage uri-codierte Zeichenfolge; Timeout tritt sogar mit 1 tweet mich zurückgeschickt, nachdem noch ~ 30 Sekunden
- gesetzt ein
keepAliveAgent
meine GET-Anfrage Optionen - versucht, ein manuell gebaut (keine
npm
Modul) Mittel für die Anforderung KeepAliveInterval
gesetzt,keepaliveGracePeriod
, unddropConnectionOnKeepaliveTimeout
auf dem Socket-Server- und eine Reihe von Knoten newbish Dinge
alle ohne Erfolg. Die App funktioniert 30 Sekunden lang wunderbar. Dann hängt es sich auf.
Meine nächste Führung: Twitter erfordert Application-only authentifizierte Anfragen über HTTPS gesendet werden. Ich habe in meinem Code für die verschiedenen Sicherheitsstufen keine Bestimmungen getroffen. Ich werde das jetzt weiter verfolgen - und schauen, ob die SO-Community irgendwelche Gedanken hat. Jede Hilfe, die Sie anbieten können, wird sehr geschätzt!
Hier ist der Code, auf das Wesentliche abgespeckte:
// 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();
});
});
Auch auf der Web-Socket-Client-Seite, die ich habe:
client.connect('ws://localhost:8080/', 'echo-protocol', 'twitterQuery');
Und hier sind die Module von Relevanz in meinem server.js:
var util = require('util');
var https = require('https');
var http = require('http');
var WebSocketServer = require('websocket').server;
var HttpsAgent = require('agentkeepalive').HttpsAgent;
Nur ein Kopf hoch: Wenn Sie 'npm websocket' verwenden und auf das gleiche Problem stoßen, lesen Sie diese Dokumentation [hier] (https://github.com/theturtle32/WebSocket-Node/blob/master /docs/WebSocketServer.md#server-config-options) - obwohl die Standardeinstellungen nicht als gewährt gelten. Setzen Sie 'keepalive: true' manuell, mit einem kurzen Intervall, um dasselbe zu erreichen, was ich oben getan habe. –