Convert Console output from Node to a webpage? - javascript

I wrote a piece of code that allows me search for all tweets hash tagged hello.
var stream = T.stream('statuses/filter', { track: 'hello', stall_warnings: true });
var counter = 0;
if (stream) {
console.log('connected!');
};
stream.on('tweet', function (tweet) {
console.log('tweet: '+ tweet.text);
console.log('by:' + ' #' + tweet.user.screen_name);
console.log('date:'+ ' ' + tweet.created_at + ' | ' + counter);
counter++;
});
How do I go about redirecting this so that I can create a web page that looks like a Twitter stream data, or something of the sort? Maybe using AngularJS.

You will have to create a web server first, try express.
then you can use something like sockets.io to communicate from the server to your client web page.
then on the webpage you must handle the messages to display them (angular, or maybe just jQuery) - basically on tweet you will send a message from your server to the client web page through socket.io, then your dront end javascript will get the message, parse it and decide how to display it.
Have a look at Sails.js, it's basically express with sockets integrated and a few more things
edit
say you export your server in server.js,
var http = require('./server.js');
var io = require('socket.io')(http);
stream.on('tweet', function (tweet) {
io.sockets.emit("new tweet", {
text: tweet.text,
by: tweet.user.screen_name,
date: tweet.created_at,
counter: counter++;
});
});
require('socket.io')(http) starts the "socket manager" on your server (and also publishes the js client side code for it), so clients can connect to your server through sockets.
io.sockets.emit will send a message to all connected clients.
on your web page you must have something like this
<div id="tweets"></div>
<script src="/your/js/jquery.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on("new tweet", function(tweet) {
$('#tweets').append('tweet: ' + tweet.text + '<br>');
$('#tweets').append('by:' + ' #' + tweet.by + '<br>');
$('#tweets').append('date:'+ ' ' + tweet.date + ' | ' + tweet.counter + '<br>');
});
</script>
the library /socket.io/socket.io.js was published by that require('socket.io')(http) from earlier, so we can use it on our clients.
the call io() basically connects to the server, and returns a handle to that connection (socket), we use that to receive all messages from the server, and on each message you can write the contents to the page anyway you want.

With socket.io you can broadcast events from the server to the client, in this case you could do something like this :
stream.on('tweet', function (tweet) {
io.sockets.emit("new tweet", tweet);
counter++;
});
And you could receive that event on the client-side like this :
var socket = io();
socket.on("new tweet", function(tweet){
//Do something with the tweet
});
This is a very basic and generic example, for more information you can look at the official documentation here.

Related

Can't connect to localhost Mosquitto Broker with Javascript?

I have a raspberry pi with a Mosquitto Broker running on it connected to a sensor module with MQTT Protocol inbuilt. If I use this code in terminal, I can subscribe and see my data coming back.
mosquitto_sub -h 169.254.118.199 -t Advantech/00D0C9FA9984/data
When using a websocket method in my HTML/Javascript I can't make a connection. I am not 100% sure what port I need to specify, I have seen most posts using port 1883 but this doesn't seem to work. In terminal there is no port required.
This is working when running in the Terminal, I want to perform the same task through my web application.
My mosquitto.conf looks like this:
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example
pid_file /var/run/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
#log_dest file /var/log/mosquitto/mosquitto.log
log_dest topic
log_type error
log_type warning
log_type notice
log_type information
include_dir /etc/mosquitto/conf.d
The webpage i am connecting to us http://192.168.1.40:5000/
In the web browser console, I can see that the connection request is timing out.
<div class="wrapper">
<h1>mqtt-demo</h1>
<form id="connection-information-form">
<b>Hostname or IP Address:</b>
<input id="host" type="text" name="host" value="169.254.118.199">
<br>
<b>Port:</b>
<input id="port" type="text" name="port" value="1883"><br>
<b>Topic:</b>
<input id="topic" type="text" name="topic"
value="Advantech/00D0C9FA9984/data"><br><br>
<input type="button" onclick="startConnect()" value="Connect">
<input type="button" onclick="startDisconnect()"
value="Disconnect">
</form>
<div id="messages"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-
mqtt/1.0.1/mqttws31.js" type="text/javascript">
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
// Called after form input is processed
function startConnect() {
// Generate a random client ID
clientID = "clientID-" + parseInt(Math.random() * 100);
// Fetch the hostname/IP address and port number from the form
host = document.getElementById("host").value;
port = document.getElementById("port").value;
// Print output for the user in the messages div
document.getElementById("messages").innerHTML += '<span>Connecting to:
' + host + ' on port: ' + port + '</span><br/>';
document.getElementById("messages").innerHTML += '<span>Using the
following client value: ' + clientID + '</span><br/>';
// Initialize new Paho client connection
client = new Paho.MQTT.Client(host, Number(port), clientID);
// Set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// Connect the client, if successful, call onConnect function
client.connect({
onSuccess: onConnect,
});
}
// Called when the client connects
function onConnect() {
// Fetch the MQTT topic from the form
topic = document.getElementById("topic").value;
// Print output for the user in the messages div
document.getElementById("messages").innerHTML += '<span>Subscribing to: '
+ topic + '</span><br/>';
// Subscribe to the requested topic
client.subscribe(topic);
}
// Called when the client loses its connection
function onConnectionLost(responseObject) {
document.getElementById("messages").innerHTML += '<span>ERROR:
Connection lost</span><br/>';
if (responseObject.errorCode !== 0) {
document.getElementById("messages").innerHTML += '<span>ERROR: ' +
+ responseObject.errorMessage + '</span><br/>';
}
}
// Called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived: " + message.payloadString);
document.getElementById("messages").innerHTML += '<span>Topic: ' +
message.destinationName + ' | ' + message.payloadString + '</span>
<br/>';
}
// Called when the disconnection button is pressed
function startDisconnect() {
client.disconnect();
document.getElementById("messages").innerHTML +=
'<span>Disconnected</span><br/>';
}
</script>
</head>
<head>
<meta http-equiv="refresh" content="450">
</head>
</html>
I expect a successful connection and the MQTT payload data. I am fairly new to MQTT.
As I said in the comments by default mosquitto does not configure a MQTT over WebSockets listener by default.
The Paho MQTT JavaScript client can only connect to a broker via MQTT over WebSockets.
To add a MQTT over WebSockets you need to add the following to the mosquitto.conf file (or to a file in /etc/mosquitto/conf.d)
listener 8083
protocol websockets
You would then need to make sure the client is connecting to port 8083

Session is not open when connecting to autobahn js

I'm having trouble while developing chat-like feature to my socket server.
First let me give you a little bit of my code:
document.conn = new ab.Session('ws://127.0.0.1:8090',
function () {
console.log('AB:Connected!');
conn.subscribe('room_1', function (topic, data) {
console.log('New message published to room "' + topic + '" : ' + data.content + ' by:' );
console.log(data);
});
},
function () {
console.warn('WebSocket connection closed');
},
{'skipSubprotocolCheck': true}
);
Currently it's attached to document just to try it out, the error I'm getting is as follows:
"Session not open"
I'm a bit confused about this error and it's origin, should I somehow define the connection?
do you start your socket server through cmd.exe ?
you need to use this command to start the server:
php c://wamp64/www/yourproject/bin/push-server.php

Restarting Supervisor and effect on FlaskSocketIO

In my index.html (HTML/Javascript) I have:
$(document).ready(function(){
namespace = '/test';
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
socket.on('connect', function() {
socket.emit('join', {room: 'venue_1'});
});
socket.on('my response', function(msg) {
$('#log').append('<br>Received #' + ': ' + msg.data);
});
});
On my Server I have:
#socketio.on('connect', namespace='/test')
def test_connect():
if session.get('venue_id'):
emit('my response', {'data': 'Connected'})
session.pop('venue_id', None)
else:
request.namespace.disconnect()
#socketio.on('join', namespace='/test')
def join(message):
join_room(message['room'])
room = message['room']
emit('my response', {'data': 'Entered the room ' + message['room']})
After logging in, I set session['venue_id'] = True and move to index.html. The output I get is:
Received #: Connected
Received #: Entered the room venue_1
My question: After the initial run, I keep the index.html page open and then stop and start my project through supervisor. At this point why do I get the same output as above? I would have thought that after the initial connect, venue_id would have been removed from the session and hence request.namespace.disconnect() would be called?
Could someone please explain to me the sequence of events here?
Thanks
The Socket.IO client has a reconnect logic built in. If the server goes away there is the expected disconnect, but right away the client starts to connect again, and obviously succeeds very quickly since the restart has a very short down time.

node, socket.io - update client when new entry added to news feed?

I've created client and server of node with socket.io. server is executing 4 get requests of news feed and fetched the data. These data is sent to the client with socket.io.
client is displaying news feed on the occurrence of specific socket.io event.
This works well for once. Here is the code and working fiddle
server.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, redis = require("redis");
var http = require("http");
// initialize the container for our data
var data = "";
var nfs = [
"http://economictimes.feedsportal.com/c/33041/f/534037/index.rss",
"http://www.timesonline.co.uk/tol/feeds/rss/uknews.xml",
"http://www.independent.co.uk/news/business/rss",
"http://www.dailymail.co.uk/money/index.rss"
];
//setInterval(function() {
for(var i=0; i<nfs.length; i++){
//console.log(nfs[i]);
http.get(nfs[i], function (http_res) {
// this event fires many times, each time collecting another piece of the response
http_res.on("data", function (chunk) {
// append this chunk to our growing `data` var
data += chunk;
});
// this event fires *one* time, after all the `data` events/chunks have been gathered
http_res.on("end", function () {
// you can use res.send instead of console.log to output via express
console.log("data received");
});
});
}
//}, 30000);
app.listen(8080);
function handler (req, res) {
fs.readFile(__dirname + '/client.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
//setInterval(function() {
socket.emit('news', data);
/*socket.on('my other event', function (data) {
console.log(data);
});*/
//}, 5000);
});
client.html
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
//socket io client
var socket = io.connect('http://localhost:8080');
//on connetion, updates connection state and sends subscribe request
socket.on('connect', function(data){
setStatus('connected');
socket.emit('subscribe', {channel:'notif'});
});
//when reconnection is attempted, updates status
socket.on('reconnecting', function(data){
setStatus('reconnecting');
});
//on new message adds a new message to display
socket.on('news', function (data) {
console.log(data);
//socket.emit('my other event', { my: 'data' });
addMessage(data);
});
/*socket.on('news', function (data) {
debugger;
socket.emit('my other event', { my: 'data' }
var msg = "";
if (data) {
msg = data;
}
addMessage(msg);
});*/
//updates status to the status div
function setStatus(msg) {
$('#status').html('Connection Status : ' + msg);
}
//adds message to messages div
function addMessage(msg) {
//debugger;
var $xml = $(msg);
var html = '';
$xml.find("item").each(function() {
var $item = $(this);
html += '<li>' +
'<h3><a href ="' + $item.find("link").text() + '" target="_new">' +
$item.find("title").text() + '</a></h3> ' +
'<p>' + $item.find("description").text() + '</p>' +
// '<p>' + $item.attr("c:date") + '</p>' +
'</li>';
});
$('#result').prepend(html);
}
</script>
</head>
<body>
<div id="status"></div><br><br>
<ul id="result"></ul>
</body>
</html>
What I understand about socket.io is that we don't need long server polling and so how do server come to know that news is added to the respected news feed.
How do I update the client with newly added news when news is added to the news feed rss ???
Update
Ok so from all the responses I get the point that it is not possible for socket.io to know that new entry has been added. So, how do I know (which tools/libraries do require to know that new entry has beed added and update the client as well) ???
Retrieving the messages from the news feeds are completely independent of socket.io unless the news feeds implement sockets on their end and your server becomes their client. So you will have to continue to poll them with http requests to know whether they have updated data.
In order to notify your clients of the update you would just emit the news event. Presumably you would have logic on the server to make sure you are only sending events which have not previously be sent.
There is no way for "node" to know when a new entry is added to the news feed. You will have to poll the news service like you are doing now. This really has nothing to do with Node or Socket.io unless I completely misunderstand what you are asking.

Why is client disconnecting and reconnecting in node + express + socket.io + jade simple app

I created a simple application as an attempt to integrate node, express, socket.io, and jade. The user enters some string ("tool ID") in a text field and clicks a submit button. That text is simply converted to all uppercase and the result is appended to the results section on the page. The results should be automatically updated for other clients viewing the page.
It mostly works. However the problem is that right after the user clicks the submit button on the page to submit the tool ID, the node console and browser javascript console both show the client disconnecting and then reconnecting.
To the user it looks like the results are updated correctly for a fraction of a second. Then the results go blank for another fraction of a second. Then the results are redisplayed. Since I am showing the user's session ID with the results, I can see that the session ID changes during the short time while the results go blank.
Note that if a different client is simply viewing the page, but not otherwise interacting, the results are updated smoothly (no brief time of results going blank) and that client doesn't seem to be disconnecting at all.
I don't want the client to disconnect and reconnect when they click the submit button on the form. Can someone tell me why this is happening and how I should be doing it properly?
My app.js (server)
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
io = require('socket.io').listen(server); // without the var, this becomes available to other files like routes.
var path = require('path');
var routes = require('./routes/routes');
var process = require('./routes/process');
var _ = require("underscore");
// all environments
app.set('port', 3097);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
//app.use(express.logger('dev'));
app.use(express.bodyParser()); //Tells server to support JSON, urlencoded, and multipart requests
app.use(express.methodOverride());
app.use(express.cookieParser('i7iir5b76ir857bveklfgf'));
app.use(express.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
var toolIDs = [];
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
io.on("connection", function(socket) {
console.log("Client connected. Sending Update");
socket.on("toolsRequest", function() {
socket.emit('toolsReady', {toolIDs: toolIDs}); //This should go to the client that just connected.
});
socket.on("disconnect", function() {
console.log("Client Disconnected");
});
socket.on("toolsUpdate", function(data) {
processedToolID = process.process(data.toolID);
toolIDs.push({id: data.id, inputToolID: data.toolID, outputToolID: processedToolID});
io.sockets.emit("toolsUpdated", {toolIDs: toolIDs}); //This should go to all clients
console.log('Results Updated - notifying all clients');
});
});
// display main page
app.get('/', routes.home);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
My routes.js
/*
* GET home page.
*/
exports.home = function(req, res){
res.render('home', { title: 'Tool'});
console.log("Just called route.home");
};
My home.jade
doctype 5
html
head
title= title
link(rel='stylesheet', href='/bootstrap/css/bootstrap.min.css')
link(rel='stylesheet', href='/bootstrap/css/bootstrap-responsive.min.css')
script(src='/socket.io/socket.io.js')
script(src="http://code.jquery.com/jquery.min.js")
script(src='/js/index.js')
block content
#wrapper
h1
a(href='/') TOOL
#display
div.row-fluid
div.inlineBlock
form#toolForm
label Tool ID
input(type="text", placeholder="e.g. abc123")#toolID
span.help-block You may enter a string.
button(class="btn")#submit
| Submit
br
div.inlineBlock.topAligned
h2 Results
br
div#results
br
My index.js (client)
function init() {
/*
On client init, try to connect to the socket.IO server.
*/
var socket = io.connect('http://example.com:3097/');
//We'll save our session ID in a variable for later
var sessionID = '';
//Helper function to update the results
function updateResults(toolIDs) {
$('#results').html('');
for (var i = 0; i < toolIDs.length; i++) {
$('#results').append('<span id="' + toolIDs[i].id + '">' + '<b>Creator ID:</b> ' + toolIDs[i].id + ' <b>Your ID:</b> ' + sessionID + ' <b>Input Tool:</b> ' + toolIDs[i].inputToolID + ' <b>Output Tool:</b> ' + toolIDs[i].outputToolID + (toolIDs[i].id === sessionID ? '<b>(You)</b>' : '') + '<br /></span>');
}
}
/*
When the client successfully connects to the server, an
event "connect" is emitted.
*/
socket.on('connect', function () {
sessionID = socket.socket.sessionid;
// Note this appears in the browser Javascript console, not node console
console.log('You are connected as: ' + sessionID);
socket.emit('toolsRequest'); //Request the tools data so we can update results
});
socket.on('toolsReady', function(data) {
updateResults(data.toolIDs);
console.log('Results have been updated from socket.on.toolsReady');
});
socket.on('toolsUpdated', function (data) {
updateResults(data.toolIDs);
console.log('Results updated from socket.on.toolsUpdated');
});
/*
Log an error if unable to connect to server
*/
socket.on('error', function (reason) {
console.log('Unable to connect to server', reason);
});
function getCitations() {
var toolID = $('#toolID').val()
socket.emit('toolsUpdate', {id: sessionID, toolID: toolID});
}
$('#submit').on('click', getCitations);
}
$(document).on('ready', init);
Here's what I see in the node console when a client clicks the submit button:
debug - websocket writing 5:::{"name":"toolsUpdated","args":[{"toolIDs":[{"id":"5a1dfX2dmxcogYT_11e8","inputToolID":"a123123","outputToolID":"A123123"},{"id":"OIuqao6TsTeddQm111e-","inputToolID":"1abcdefg","outputToolID":"1ABCDEFG"},{"id":"Qr_YQ2ZhQHbDpBlk11e_","inputToolID":"abcdefg","outputToolID":"ABCDEFG"}]}]}
Results Updated - notifying all clients
Just called route.home
info - transport end (socket end)
debug - set close timeout for client Qr_YQ2ZhQHbDpBlk11e_
debug - cleared close timeout for client Qr_YQ2ZhQHbDpBlk11e_
debug - cleared heartbeat interval for client Qr_YQ2ZhQHbDpBlk11e_
Client Disconnected
debug - discarding transport
debug - served static content /socket.io.js
debug - client authorized
info - handshake authorized 2bPKGgmLdD4fp-vz11fA
debug - setting request GET /socket.io/1/websocket/2bPKGgmLdD4fp-vz11fA
debug - set heartbeat interval for client 2bPKGgmLdD4fp-vz11fA
debug - client authorized for
debug - websocket writing 1::
Client connected. Sending Update
debug - websocket writing 5:::{"name":"toolsReady","args":[{"toolIDs":[{"id":"5a1dfX2dmxcogYT_11e8","inputToolID":"a123123","outputToolID":"A123123"},{"id":"OIuqao6TsTeddQm111e-","inputToolID":"1abcdefg","outputToolID":"1ABCDEFG"},{"id":"Qr_YQ2ZhQHbDpBlk11e_","inputToolID":"abcdefg","outputToolID":"ABCDEFG"}]}]}
Thanks, I appreciate the help.
Your submit button is actually reloading the page, which is why the socket is disconnecting, and why you see the socket response for such a short time. Just prevent the default action of the submit button. Change this:
$('#submit').on('click', getCitations);
To something similar:
$('#submit').click(function(event) {
event.preventDefault();
getCitations();
});

Categories