twitter-node detecting connection end - node.js

I'm using the twitter-node library for node.js and it works well, however I'm having some minor difficulty handling disconnects.
When twitter disconnects me (I'm connecting a second time from the same server to force a disconnect so I can make sure I'm handling these sorts of issues) it doesn't produce an error or an end event.I thought the following would handle it:
var twitter = new TwitterNode({
user : opts.account,
password : opts.password,
track : opts.hashtags,
follow : opts.follow
});
// omitted handlers for receiving tweets/deletes/limit info, but its there
twitter.addListener('error', function(error) {
console.log('error occoured:' + error.message);
}).addListener('end', function(resp) {
sys.puts("wave goodbye... " + resp.statusCode);
}).stream();
However, I don't get either the message from 'end' or 'error' when I'm disconnected. Anyone familiar with this issue?

For anyone having this same issue:
There's no notification from twitter-node because it doesn't handle the https libraries close event - by going into the source and adding:
response.on('close', function() { twit.emit('close',this); }
The library now emits a close event when the connection is closed by the remote server (twitter) and you can handle it with a listener in your code like this:
twitterStreamReader = new TwitterNode({...});
twitterStreamReader.addListener('close', function(resp) {
sys.puts('The server connection has been closed. You may want to do something about that.');
});

Related

How get socket.io Broadcast messages on client side?

I'm trying send a broadcast message from Server to clients, follow the docs avaiable at https://socket.io/docs/
And doesn't work
I tryed of two forms at server side
io.emit('update_status',{ device: device.id, status: 'Dead'});
or
socket.broadcast.emit({ device: device.id, status: 'Dead'});
At Client Side
socket.on('update_status',function(data) {
console.log('update_status',data);
});
or
socket.on('message',function(data) {
console.log('message ',data);
});
Any message arrives at client side.
I need to understand what I am doing wrong.
UPDATE
I found the solution with the help of #Azka. I do not know why, but using the variable socket soon after initiate the socket on the client side works, started to receiving messages.
var socket = io ();
socket.on ('message', function (data) {
console.log ('message', data);
});
Another thing with helps me is using debug at client side.
Paste at Browser console to read all incoming messages
localStorage.debug = 'socket.io-client:socket';
The Problem is: After the socket was added at room stopped to Receive Broadcast
Any sugestions?

Terminate EventSource event listener?

I'm trying to work around a problem to do with rest streaming between the Nest API and a service (ST) that does not support streaming.
To get around this, I have built a service on Sails which takes a post request from ST containing the Nest Token, and then triggers an EventSource event listener that sends the data back to ST.
It is heavily based off the Nest rest-streaming example here:
https://github.com/nestlabs/rest-streaming and my code is as follows:
startStream: function(req, res) {
var nestToken = req.body.nestToken,
stToken = req.body.stToken,
endpointURL = req.body.endpointURL,
source = new EventSource(sails.config.nest.nest_api_url + '?auth=' + nestToken);
source.addEventListener('put', function(e) {
var d = JSON.parse(e.data);
var data = { devices: d.data.devices, structures: d.data.structures},
config = { headers : {'Authorization': 'Bearer ' + stToken}};
sendData(endpointURL, data, config);
});
source.addEventListener('open', function(e) {
console.log("Connection opened");
});
source.addEventListener('auth_revoked', function(e){
console.log("Auth token revoed");
});
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
console.error('Connection was closed! ', e);
} else {
console.error('An unknown error occurred: ', e);
}
}, false);
}
};
The problem I foresee though is that once a request is received by the node server, it start the event listener, however I cannot for the life of me figure out how I can kill the event listener.
If I cannot figure out a way to stop this, then every EventListener will run indefinitely which is obviously not suitable.
Has anyone got any suggestions on how to overcome the issue?
Each SSH client connection is a dedicated socket.
If a particular client doesn't want event streaming, don't make the connection. If they start event streaming, but want to turn it off, call source.close();source=NULL;
If from server-side you want to stop sending the messages, close the socket.
You didn't show the server-side code, but if it is running a dedicated process per SSE client then you just exit the process. If you are maintaining a list of sockets, one per connected client, close the socket. On node.js you might be running a function on setInterval. To close the connection you do and clearInterval() and response.end();.

How to close a http.ServerResponse prematurely?

Say that an error occurs when I'm in the middle of sending a chunked response from my http server that I'm writing in Node.js. There's no way to send an error message to the client at this point, and I figure that this answer is correct on what to do in this situation:
All you can do is close the connection. Either the client does not receive all of the headers, or it does not receive the terminating 0-length chunk at the end of the response. Either way is enough for the client to know that the server encountered an error during sending.
So the question is, how do I do this on my http.ServerResponse object? I can't call end, because then the client will think everything went well, and there is no close method. There is a 'close' event, but I get the feeling that's something I'm supposed to listen for in this context, not emit myself, right?
I do it in the following manner:
function respDestroy()
{
this._socket.destroy();
}
function respReply(message, close)
{
if (!close)
this.end(message);
else
this.end(message, function(){ this.destroy(); });
}
server.on('request',
function(req, resp)
{
resp._socket = resp.socket; // `socket` field is nulled after each `end()`
resp.destroy = respDestroy;
resp.reply = respReply;
...
});
You can modify respReply to accept status code and status message as well.

Why so many connections established?

I am writing a program to work with rabbitmq via amqp on heroku.
The part of my program have this code:
console.log( 'APP START' );
//Connect to db and start
global.controllers.db.opendb(dbsettings, function(error,db){
if (!error){
global.db = db;
console.log( 'DB: connection to database established.' );
var con = amqp.createConnection( { url: global.queue.producers.host } );
con.on( 'ready', function() {
console.log( 'mq: producers connection ready.' );
});
}
});
As I understood from documentation I should get only one message upon successful connection to queue service.
Is there any particular reason why my output have a lot of lines containing mq: producers connection ready. like this then?
The amqp-node library automatically reconnects either when the connection is lost or when an error occurs in your code. I can't see anything wrong with your code above, but if any exceptions are thrown in your rabbit-related code (also in other places, such as connecting and subscribing to queues) amqp-node will try to reestablish your connection - and keep getting the same exception and keep retrying.

How to disable Multiplexing with Socket.io

I am using Socket.io to stream live tweets to my users using Twitter's Streaming API (my implementation is more or less based on this tutorial).
The problem is that every time a connection event is fired by Socket.io the newly connected client causes every other client connected to the server to cease updating. While it would take too long to go through all the hacks that I tried, I will say that I played with it enough that I believe the problem is caused by Socket.io's multiplexing of the connections from multiple clients (enabled by default) as a performance boost to allow multiple clients or connections to share the same underlying socket. In short, I believe this to be the case because I don't think it would be possible for new connections to affect older connections in this manner if not for the connection multiplexing. In other words, if a new, independent connection with its own underlying (TCP) socket were created every time a client connected it would be impossible for this to occur since one connection would know nothing about the other and therefore couldn't affect any other client's state as is currently happening. This also leads me to believe that simply disabling the multiplexing functionality would be the simplest way to get around this problem since I am not concerned about scaling because Node.js already handles all the concurrency I'm likely to need to handle very adequately.
I have gone through Socket.io's documentation but could not see where the ability to "demultiplex" the connections is exposed via the API, so if anyone knows how to do this I'd create appreciate your response.
My code below is pretty standard and simple. But just to be clear, the issue is that whenever a new client connects to Socket.io every other client stops receiving new tweets and updates are no longer pushed to the older client unless I refresh the browser in which case the newly refreshed client will begin to update and receive fresh tweets again, but the other still connected clients will then stop updating.
Server-side Code:
// Code also uses ntwitter (https://github.com/AvianFlu/ntwitter) as an abstraction over Twitter's Streaming API
io.sockets.on('connection', function (socket) {
tweet.stream('statuses/filter', { track : 'new orleans' }, function (stream) {
stream.on('data', function (data) {
// The following lines simply pre-process data sent from Twitter so junk isn't
// unnecessarily sent to the client.
if (data.user) {
tweets = {
text : data.text,
image : data.user.profile_image_url,
user : data.user.name
};
var t = JSON.stringify(tweets);
console.log(t);
socket.send(t);
}
});
});
});
Client-Side Code
// Notice the option that I passed in as the second argument. This supposedly forces every
// new client to create a new connection with the server but it either doesn't work or I'm
// implementing it incorrectly. It is the very last configuration option listed in the
// documentation linked to above.
var socket = io.connect('http://' + location.host, {'force new connection' : true });
socket.on('message', function (tweet) {
var t = JSON.parse(tweet);
if (t.image) {
$('.hero-unit').prepend('<div class="media"><a class="pull-left" href="#"><img class="media-object" alt="64x64" style="width: 64px; height: 64px;" src="' + t.image + '"></a><div class="media-body"><h4 class="media-heading">' + t.user + '</h4>' + t.text + '</div></div>');
}
});
If I am thinking of this incorrectly or if there's something wrong with my code I am definitely open to any suggestions. I'd also be happy to reply with any additional details.
I would try something like this
Serverside:
io.sockets.on('connection', function (socket) {
//Other Connectiony goodness here.
});
});
tweet.stream('statuses/filter', { track : 'new orleans' }, function (stream) {
stream.on('data', function (data) {
// The following lines simply pre-process data sent from Twitter so junk isn't
// unnecessarily sent to the client.
if (data.user) {
tweets = {
text : data.text,
image : data.user.profile_image_url,
user : data.user.name
};
var t = JSON.stringify(tweets);
console.log(t);
io.sockets.emit("tweet", t);
}
});
Client-side:
var socket = io.connect('http://' + location.host, {'force new connection' : true });
socket.on('tweet', function (tweet) {
var t = JSON.parse(tweet);
if (t.image) {
$('.hero-unit').prepend('<div class="media"><a class="pull-left" href="#"><img class="media-object" alt="64x64" style="width: 64px; height: 64px;" src="' + t.image + '"></a><div class="media-body"><h4 class="media-heading">' + t.user + '</h4>' + t.text + '</div></div>');
}
});
Basically have the stream from twitter outside your socket, and then on a new tweet emit a message to all connected.

Resources