heroku http streaming (sse) disconnect not detected with express.js - heroku

Heroku is not detecting when a client disconnects.
I cloned their starter app and added a couple lines for sse:
var sse = require('connect-sse')();
app.get('/testing', sse, function(req, res, next) {
var interval;
interval = setInterval(function() {
var date;
date = new Date();
res.json({
ping: date
});
return console.log(date);
}, 2000);
return req.on('close', function() {
clearInterval(interval);
return console.log("cleared");
});
});
When I go to my app I see the correct reponse:
id: 0
data: {"ping":"2014-01-05T23:53:49.835Z"}
id: 1
data: {"ping":"2014-01-05T23:53:51.839Z"}
But after I close the browser tab heroku does not register that I did.
With heroku logs -t I keep getting the date printed out and never cleared
This works locally with foreman start but not on heroku.
Anyone know what I am doing wrong?

Based on the documentation for the connect-sse node module, it looks like you should be referring to the sse middleware without parentheses, like so:
app.get('/testing', sse, function(req, res, next) {
// ...
});

Related

socket.io data from server to client

server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
app.use(express.static(__dirname + '/public'));
io.on('connection', function(client) {
console.log('Client connected...');
client.on('join', function(data) {
console.log(data);
io.emit('messages', 'Hello');
});
});
index.html
<script>
var socket = io.connect('http://localhost:7777');
socket.on('connect', function(data) {
socket.emit('join', 'Hello World from client');
});
socket.on('messages', function(data) {
alert(data);
});
</script>
I tried to implement very basic of Socket.io.
However, data sending from client to server is available but from server to client doesn't work.
In the command running server.js, 'Hello World from client' is printed. However, alert window doesn't work in the web browser.(I've also tried to console.log).
How to solve this?
Editted
I've put server.js codes in the app.get('/', function(req, res)){ ... }
Then, it doesn't work. Why it doesn't work in app.get?
Try this, I hope it works:
io.on('connection', function(client) {
console.log('Client connected...');
client.on('join', function(data) {
console.log(data);
io.emit('join', data); //this code sending data from server to client
});
});
If you're just trying to fetch some data with an Ajax call such as /test, then there is no need to use socket.io. That's just a classic request/response.
app.get('/test', function(req, res) {
// collect your data and then send it as a response
res.json(data);
});
If you're just trying to incorporate data into a web page that is requested, then you can use res.render() with the template engine of your choice (ejs, handlebars, pug, etc...). That would typically look like this:
app.get('/test', function(req, res) {
// collect your data and then pass it to res.render() to render your
// your template using that data
res.render('someTemplateName', data);
});
The main thing that socket.io is useful for is "pushing" data from server to client without a client request. So, if something happened on the server that the client was not aware of and the server wanted to tell the client about it, then socket.io would be used for that. The classic example is a chat app. Person A sends a chat message to the server that is addressed to Person B. The server receives that message and then needs to "push" it to Person B. That would be perfect for an already connected socket.io connection because the server can just push the data directly to the Person B client, something the server can't do with request/response (since there is no request from person B).
If you still think you need socket.io, then please describe exactly what you're trying to do with it (step by step what you're trying to send to the client).
socket.on("message",function (reply_data) {
console.log('inside on message functions ')
console.log(reply_data);
})
please change 'messages' to "message" that worked for me

Parse express server side login using express-session

I'm using parse on node. I have an express app, and a JS browser app, that is hosted off the express server.
At the moment the app has it's own login. It logs the user in on the client, and the client remains logged in.
I want to be able to log the client in via an express route /login. When they log in via this route, i want to log them in on the client side.
I have poured over documentation on this but I have struggled to find any real examples of how this is all done.
Here is some code i have found:
var cookieSession = require('cookie-session'),
// I added this require as it seems the code is using it;
session = require('express-session');
app.use(cookieSession({
name: COOKIE_NAME,
secret: "SECRET_SIGNING_KEY",
maxAge: 15724800000
}));
//
// This will add req.user if they are logged in;
//
app.use(function (req, res, next) {
Parse.Cloud.httpRequest({
url: 'http://localhost:1337/parse/users/me',
headers: {
'X-Parse-Application-Id': 'myAppId',
'X-Parse-REST-API-Key': 'myRestAPIKey',
'X-Parse-Session-Token': req.session.token
}
}).then(function (userData) {
req.user = Parse.Object.fromJSON(userData.data);
next();
}).then(null, function () {
return res.redirect('/login');
});
});
//
// login route;
//
app.post('/login', function(req, res) {
Parse.User.logIn(req.body.username, req.body.password).then(function(user) {
req.session.user = user;
req.session.token = user.getSessionToken();
res.redirect('/');
}, function(error) {
req.session = null;
res.render('login', { flash: error.message });
});
});
//
// and logout.
//
app.post('/logout', function(req, res) {
req.session = null;
res.redirect('/');
});
This looks pretty good, but this won't add a session on the client? How do parse the server login down to the client; Do i pass the session Token and use it on the client?
//
// If i call this code in the browser, i want the logged in user;
//
var current_user = Parse.User.current();
I have been unable to find any real code on-line that demonstrates all of this in the best-practice manner.
Is this the 'best practice' known solution or is there a better way of doing this?

Stripe Payments with parse server cloud code

I have this code included in my main.js:
var stripe = require("/cloud/stripe.js")("sk_test_*********");
//create customer
Parse.Cloud.define('createCustomer', function (req, res) {
stripe.customers.create({
description: req.params.fullName,
source: req.params.token
//email: req.params.email
}, function (err, customer) {
// asynchronously called
res.error("someting went wrong with creating a customer");
});
});
After pushing this code to my Heroku server the logs indicate that: Error: Cannot find module '/cloud/stripe.js'
I have also tried var stripe = require("stripe")("sk_test_*********"); but this returns the same error. Whenever I try add this new module to my server the whole server becomes dysfunctional. What workarounds are there to this? Thanks
Have you added Stripe to the requirements of your package.json file for your node project? If so, you should be able to reference it using the term require('stripe') as opposed to what you're doing.
I'll tell you what worked for me, I racked my brain on this for a day. Instead of using Cloud Code to make a charge, create a route on index.js. Something like this in index.js
var stripe = require('stripe')('sk_test_****');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: false
}));
app.post('/charge', function(req, res){
var token = req.body.token;
var amount = req.body.amount;
stripe.charges.create({
amount: amount,
currency: 'usd',
source: token,
}, function(err, charge){
if(err)
// Error check
else
res.send('Payment successful!');
}
});
I call this using jQuery post but you could also use a form.

Socket.io client only joins room on every other connection

I've been trying to make a basic notification system that uses rooms in Socket.io. However, for some reason, it only works every other time you refresh the page.
I've simplified the code to make it easier to debug, but the issue remains. Each time I refresh the page, everything seems to work except joining a room (which only works half the time). What could be going on?
edit: I'm using Socket.io version 1.1.0 and Node.js version 0.10.31
edit2: Added FunnyLookinHat's suggestion (but it still doesn't solve the problem)
Client-Side Code:
socket = io.connect('example.com:8081'),
socket.on('connect', function () {
socket.on('startup', function(data) {
console.log(data.message);
});
socket.emit('joinRoom');
});
Server-Side Code:
var io = require('socket.io').listen(8081);
io.sockets.on('connection', function (socket) {
console.log(socket.id + ' connected!');
socket.emit('startup', { message: 'Socket started!' });
socket.on('joinRoom', function(){
console.log(socket.id + ' joining room lobby'); // prints on every other request
socket.join('lobby');
});
socket.on('disconnect', function() {
console.log(socket.id + ' disconnected!');
});
});
Client Console:
Socket started!
(refreshed page)
Socket started!
Server Console:
UIBqVuOiF1fegMIMAAAB connected!
UIBqVuOiF1fegMIMAAAB joining room lobby
UIBqVuOiF1fegMIMAAAB disconnected!
(refreshed page)
x3nMilBOjjFVjBFJAAAC connected!
(after about a minute once the client window has been closed or refreshed)
x3nMilBOjjFVjBFJAAAC disconnected!
Race condition! Try doing the following in your client code:
socket = io.connect('example.com:8081'),
socket.on('connect', function () {
socket.on('startup', function(data) {
console.log(data.message);
});
socket.emit('joinRoom');
});

a file upload progress bar with node (socket.io and formidable) and ajax

I was in the middle of teaching myself some Ajax, and this lesson required building a simple file upload form locally. I'm running XAMPP on windows 7, with a virtual host set up for http://test. The solution in the book was to use node and an almost unknown package called "multipart" which was supposed to parse the form data but was crapping out on me.
I looked for the best package for the job, and that seems to be formidable. It does the trick and my file will upload locally and I get all the details back through Ajax. BUT, it won't play nice with the simple JS code from the book which was to display the upload progress in a progress element. SO, I looked around and people suggested using socket.io to emit the progress info back to the client page.
I've managed to get formidable working locally, and I've managed to get socket.io working with some basic tutorials. Now, I can't for the life of me get them to work together. I can't even get a simple console log message to be sent back to my page from socket.io while formidable does its thing.
First, here is the file upload form by itself. The script inside the upload.html page:
document.getElementById("submit").onclick = handleButtonPress;
var httpRequest;
function handleResponse() {
if (httpRequest.readyState == 4 && httpRequest.status == 200) {
document.getElementById("results").innerHTML = httpRequest.responseText;
}
}
function handleButtonPress(e) {
e.preventDefault();
var form = document.getElementById("myform");
var formData = new FormData(form);
httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = handleResponse;
httpRequest.open("POST", form.action);
httpRequest.send(formData);
}
And here's the corresponding node script (the important part being form.on('progress')
var http = require('http'),
util = require('util'),
formidable = require('formidable');
http.createServer(function(req, res) {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm(),
files = [],
fields = [];
form.uploadDir = './files/';
form.keepExtensions = true;
form
.on('progress', function(bytesReceived, bytesExpected) {
console.log('Progress so far: '+(bytesReceived / bytesExpected * 100).toFixed(0)+"%");
})
.on('file', function(name, file) {
files.push([name, file]);
})
.on('error', function(err) {
console.log('ERROR!');
res.end();
})
.on('end', function() {
console.log('-> upload done');
res.writeHead(200, "OK", {
"Content-Type": "text/html", "Access-Control-Allow-Origin": "http://test"
});
res.end('received files: '+util.inspect(files));
});
form.parse(req);
} else {
res.writeHead(404, {'content-type': 'text/plain'});
res.end('404');
}
return;
}).listen(8080);
console.log('listening');
Ok, so that all works as expected. Now here's the simplest socket.io script which I'm hoping to infuse into the previous two to emit the progress info back to my page. Here's the client-side code:
var socket = io.connect('http://test:8080');
socket.on('news', function(data){
console.log('server sent news:', data);
});
And here's the server-side node script:
var http = require('http'),
fs = require('fs');
var server = http.createServer(function(req, res) {
fs.createReadStream('./socket.html').pipe(res);
});
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
socket.emit('news', {hello: "world"});
});
server.listen(8080);
So this works fine by itself, but my problem comes when I try to place the socket.io code inside my form.... I've tried placing it anywhere it might remotely make sense, i've tried the asynchronous mode of fs.readFile too, but it just wont send anything back to the client - meanwhile the file upload portion still works fine. Do I need to establish some sort of handshake between the two packages? Help me out here. I'm a front-end guy so I'm not too familiar with this back-end stuff. I'll put this aside for now and move onto other lessons.
Maybe you can create a room for one single client and then broadcast the percentage to this room.
I explained it here: How to connect formidable file upload to socket.io in Node.js

Resources