I have successfully opened a websocket connection in server to an external API to get exchange ticker data but not sure how to continuously push the data to client / AngularJS.
Here is the router code:
router.get('/live-ticker', function(req, res) {
var autobahn = require('autobahn');
var wsuri = "wss://api.poloniex.com";
var connection = new autobahn.Connection({
url: wsuri,
realm: "realm1"
});
connection.onopen = function(session) {
function tickerEvent(args, kwargs) {
res.json(args);
console.log(args);
}
session.subscribe('ticker', tickerEvent);
}
connection.onclose = function() {
console.log("Websocket connection closed");
}
connection.open();
});
What I'm attemping to do is to have the data from tickerEvent live update the controller in the front end:
app.controller('liveTickerController', function($scope, $http) {
$scope.ticker = [];
var request = $http.get('/live-ticker');
request.success(function(ticker) {
console.log(ticker); //only logging data once
$scope.liveTicker = ticker;
});
request.error(function(err) {
console.log('Error: ' + err);
});
});
How would get live updates pushed to client?
Thank you
you need to push data from the server periodically.
to get these "live updates" on the client side, a plain ajax call is not enough,
you need a realtime communication.
You should use websoket even here, with socket.io and angular socket.io for example you can handle this communication easily
Related
I'm trying to recreate the functionality of a hardware serial server with Node and it's actually working, but I'm getting errors from socket instances that have been closed.
Here's a simplified version of the app to show what I'm doing...
var net = require('net');
var SerialPort = require('serialport');
var connectionCounter = 0;
var port = new SerialPort('/dev/ttyUSB0', function () {
var server = net.createServer();
server.on('connection',function(socket) {
connectionCounter++;
var connNumber = connectionCounter;
socket.on('error', function () {
console.log('socket ' + connNumber + ' errored');
});
socket.on('data', function(data) {
port.write(data);
});
port.on('data', function(data) {
socket.write(data);
});
});
server.listen(8887, '127.0.0.1');
}
});
So the first chunk of code that's sent into the 8887 port works fine, and it returns the data back out through the socket. The errors start on the second chunk. In the example, I'm keeping a count of the socket instances and outputting the socket instance number with the error. So as the program runs, the number of sockets instances keeps going up. The most recent instance will eventually handle the data, but I can't figure out what I need to delete to clean up all of the previous socket instances so they'll stop trying to process the incoming data.
I've tried socket.end() and socket.destroy(), but those don't seem to work . Do I need to go as far as deleting the server itself and recreating it?
If anyone ever finds this and cares about what was going wrong, I was setting an event listener on the serialport object every time a new net socket was created. So even though I was deleting the socket every time it was closed, the serialport listener was trying to send data to all of the old deleted sockets. So the solution was to removeListeners from the serialport object upon closing the net socket.
you can use array for storing sockets later on you can delete. this is sample code hope you got the idea
var net = require('net');
var SerialPort = require('serialport');
var connectionCounter = 0;
var mySockets = [];
var port = new SerialPort('/dev/ttyUSB0', function () {
var server = net.createServer();
server.on('connection',function(socket) {
mySockets.push(socket);
connectionCounter++;
var connNumber = connectionCounter;
socket.on('error', function () {
console.log('socket ' + connNumber + ' errored');
});
socket.on('data', function(data) {
port.write(data);
});
port.on('data', function(data) {
socket.write(data);
});
});
server.listen(8887, '127.0.0.1');
}
//get the sockets you want to delete
var s = mySockets.pop();
s = null;
});
I'm new with node.js/express and all and I want to be able to notify any clients in browser about a new message received from some algorithm in the back-end. The publisher algorithm connect to the websocket and writes the message.
As far as I've looked there were examples which recommended websockets but I haven't been able to run that code in browser only in console.
Example client code:
var WebSocket = require('faye-websocket');
var ws = new WebSocket.Client('ws://localhost:1234');
var http = require('http');
var port = process.env.PORT || 1235;
var server = http.createServer()
.listen(port);
// receive a message from the server
ws.on('message', function(event) {
alert(JSON.parse(event.data));
});
Thank you
Found the answer after some trial/error iterations.
The algorithm now does a POST to an URL which in turn triggers a write to sockets for all connected clients via socket.io.
Client code:
var socket = io('http://localhost:7777');
socket.on('message', function (msg) {
document.body.insertAdjacentHTML( 'beforeend', '<div id="myID">'+msg+'</div>' );
});
And on the server, when client connects I retain it's socket into an array so I can write to each one:
Server code:
io.on('connection', function(socket){
console.log('a user connected: '+socket.id);
var id = clientCount++;
clientSockets[id] = socket;
socket.on('disconnect', function(){
console.log('user disconnected');
delete clientSockets[id];
socket = null
});
});
app.post('/alerts', function(req, res) {
req.accepts(['json', 'application']);
console.log("Algo did a POST on /alerts!");
// send the message to all clients
//console.log(req.body);
for(var i in clientSockets) {
clientSockets[i].send(JSON.stringify(req.body));
}
res.send(200);
});
In conclusion, I'm not using faye-websockets but instead socket.io
I'm having the most odd problem trying to send data from a client browser to my node server using SocketIO. Sending from server to client works just fine, but the other way around I get an undefined error. Here's a quick bit of what it looks like, super simple.
Node Server (app.js)
io.on("connection", function(socket) {
socket.on("pageReady", function(data) {
console.log('pageReady called');
console.log(data);
return socket.emit('newline', '###SOCKET STARTED###');
});
socket.on("disconnect", function() {
return console.log('disconnected');
});
});
Browser (client.js)
var socket;
socket = io.connect("http://localhost:5678");
socket.on("newline", function(data) {
return $('#socketData').append('<li>' + data + '</li>');
});
socket.emit("pageReady", "test");
Super simple, right? Nothing special. When I emit from server, works fine, however when the client calls "pageReady". node responds with this.
/Volumes/HOME/Users/user/git/sockettest/app.js:89
console.log(data);
^
ReferenceError: data is not defined
Data should be returning "test", but isn't. What am I doing wrong?
Your client should listen for the socket connection before attempting to emit to it:
var socket = io.connect("http://localhost:5678");
socket.on("newline", function(data) {
return $('#socketData').append('<li>' + data + '</li>');
});
socket.on("connect", function() {
socket.emit("pageReady", "test");
});
I have an app that has been maxing out the number of connection to MongoDB and I was under the assumption that if the drivers were set up correctly you didn't need to worry about closing connections.
I've seen people mention the Generic Pool module but what is the best process for closing or pooling connections using Node & MongoDB?
Here is my connection code for the app:
var sys = require("sys");
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
app.listen(1337);
io.configure(function () {
io.set('authorization', function (handshakeData, callback) {
callback(null, true);
});
});
function handler (req, res, data) {
sys.puts('request made to trackerapp.js');
res.writeHead(200);
res.end(data);
}
io.sockets.on('connection', function (socket) {
socket.on('adTracker', function (data) {
var adRequestData = data;
var databaseUrl = "mongodb://dbuser:dbpass#mongolab.com/tracker";
var collections = ["cmnads"]
var db = require("mongojs").connect(databaseUrl, collections);
db.cmnads.insert({adRequest : adRequestData},function(err, updated) {
if( err || !updated ) console.log("mongo not updated" + err);
else console.log("data stored");
});
});
});
After seeing JohnnyHK's comment I was able to pull the connection event out of the Socket.io connection and it worked fine, see the solution below:
var databaseUrl = "mongodb://dbuser:dbpass#mongolab.com/tracker";
var collections = ["cmnads"];
var db = mongojs.connect(databaseUrl, collections);
io.sockets.on('connection', function (socket) {
socket.on('adTracker', function (data) {
var adRequestData = data;
//vars for MongoDB used to be created here... so new connect function was called on every request to socket.io
db.cmnads.insert({adRequest : adRequestData},function(err, updated) {
if( err || !updated ) console.log("mongo not updated" + err);
else console.log("data stored");
});
});
});
A technique I used with my express apps that seems have some measure of success is to open a connection to a mongo instance (thereby getting a connection pool) then sharing that db (that is now in the "connected" state) instance wherever it is needed. Something like this:
server = new Server(app.settings.dbsettings.host, app.settings.dbsettings.port, {auto_reconnect: true, poolSize: 5})
db = new Db(app.settings.dbsettings.db, server, {native_parser:false})
db.open(function(err, db) {
app.db = db;
server = app.listen(app.settings.port);
console.log("Express server listening on port %d in %s mode", app.settings.port, app.settings.env);
require('./apps/socket-io')(app, server);
});
This connects to the database at the highest level in my app before the program moves into the wait listen state.
Before I used this pattern I would create a new database object whenever I needed to interact with the database. The problem I found is that the new database object would create a new thread pool, consuming a bunch of ports. These were never cleaned up properly. After a period of time the machine that hosted the app would run out of ports!
Anyway, a variation on the code I have shown should be where you should do your thinking I believe.
I write some code example that identifi connected users via socket.io... So now I must write a code on index page to comunicate with users.
The code is below and HOW to send a message to user[1] "Welcome" and for user[2] "HI men" and also limit connection fr 2 users. so when 2 user connected then anybody else cant connect..
Index.html:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
var users;
socket.on('hello', function (data) {
console.log(data.hello);
});
socket.on('listing', function (data) {
users = data;
});
socket.on('chat', function (message) {
console.log(message);
});
socket.on('message', function (message) {
console.log(message);
});
function chat (message) {
socket.emit('chat', message);
}
function message (user, message) {
socket.emit('message', {
user: user,
message: message
});
}
</script>
app.js
var express = require('express');
var app = express.createServer();
var io = require('socket.io').listen(app);
app.listen(3000);
app.use(express.static(__dirname));
var users = {};
var userNumber = 1;
function getUsers () {
var userNames = [];
for(var name in users) {
if(users[name]) {
userNames.push(name);
}
}
return userNames;
}
io.sockets.on('connection', function (socket) {
var myNumber = userNumber++;
var myName = 'user#' + myNumber;
users[myName] = socket;
socket.emit('hello', { hello: myName });
io.sockets.emit('listing', getUsers());
socket.on('chat', function (message) {
io.sockets.emit('chat', myName + ': ' + message);
});
socket.on('message', function (data) {
users[data.user].emit('message', myName + '-> ' + data.message);
});
socket.on('disconnect', function () {
users[myName] = null;
io.sockets.emit('listing', getUsers());
});
});
app.listen(process.env.PORT);
You can start by taking a look at how to configure authorization with Socket.io. The handshakeData provided by the callback can be modified there (ie: add a username property), and any changes will be accessible via socket.handshake in your app.js (via the object passed in to the callback for io.sockets.on('connection',..). Using request header information that's also accessible from the handshakeData, you can set user values within the authorization callback (ie: from a database) so you can identify the user for the given socket in your app.js.
Here's a similar example
I know it has been a long time since you asked this, but just 4 days ago I published a module for node js, express and socket.io which manages that exactly thing you wanted. Check the Usage and Example; I hope you will find this module helpful!
You can install it via NPM socket.io.users This is a node js module for socket.io applications. One user per client.
Some of the usage code:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var socketUsers = require('socket.io.users');
// ...
socketUsers.Session(app); // IMPORTANT !
// ...
var rootIo = require('socket.io')(server); // default '/' as namespace.
var chatIo = rootIo.of('/chat');
var rootUsers = socketUsers.Users; /* default '/' as namespace.
Each namespace has ITS OWN users object list,
but the Id of a user of any other namespace may
have the same value if request comes from the same client-machine-user.
This makes easy to keep a kind of
synchronization between all users of all the different namespaces. */
var chatUsers = socketUsers.Users.of('/chat'); //
rootIo.use(socketUsers.Middleware());
/* IMPORTANT but no errors if you want
to skip it for a io.of(namespace)
that you don't want the socket.io.users' support. */
chatUsers.use(socketUsers.Middleware());
chatUsers.on('connected',function(user){
console.log(user.id + ' has connected to the CHAT');
user.store.username = 'username setted by server side'; /*at the store
property you can store any type of properties
and objects you want to share between your user's sockets. */
user.socket.on('any event', function(data){
/*user.socket is the current socket, to get all connected sockets from this
user, use: user.sockets */
});
chatIo.emit('set username',user.store.username);
});
rootUsers.on('connected',function(user){
console.log('User has connected with ID: '+ user.id);
});
rootUsers.on('connection',function(user){
console.log('Socket ID: '+user.socket.id+' is user with ID: '+user.id);
});
rootUsers.on('disconnected',function(user){
console.log('User with ID: '+user.id+'is gone away :(');
});
//...server.listen blabla..