How to stop my web page rendering after socket io close - node.js

I have a NodeJS App with Socket Io integration. Now my web page and app both has been implemented but I am facing one issue during execution:
Below is my web page code:
<script>
$(document).ready(function(){
$("#batch")[0].reset();
var socket = io.connect('http://xx.xx.xxx.xx:xxxx',{'forceNew':true });
socket.on('message', function (data) {
var newtext = data;
document.batch.outputtext.value += newtext;
});
socket.on('end', function (data) {
socket.disconnect();
});
});
</script>
And my NodeJS App:
exec_script = function(resp) {
socket.on('connection', function (client) {
console.log('Connection Established');
client.on('disconnect', function () {
console.log('disconnected');
return;
});
var pyshell = new PythonShell('./test.py', options ={ mode: 'text', pythonOptions: ['-u'] });
pyshell.stdout.on('data', function(data) {
client.emit('message', data);
console.log(data);
});
pyshell.end(function(err) {
if (err) throw err;
console.log('End Script');
client.emit('end', 'end');
client.disconnect();
});
});
};
The issue I am facing is that when the Python scripts executes its output is send to browser while my browser status states "Waiting for xx.xx.xxx.xx" and in my FF I see the blue circle circling - that's fine - but even after the Python script has ended and socket disconnected explicitly I still see the browser status as "Waiting for xx.xx.xxx.xx browser title as Connecting with the blue circle rotating?
How can I close and end the connection successfully with the fact that I need the same page in the browser that is I would not navigate the user to some other page?
I tried by using response.end() but the issue I am facing is that if the request data was posted as URL form /today then calling response.end() changes the URL at browser side to http://xx.xx.xxx.xx:xxxx/today leading to a blank / error page which is what I a do not want in my case - the URL should remain as http://xx.xx.xxx.xx:xxxx?
Below is the method I am calling my exec_script method:
router.post('/', function(req, res) {
methods.process(req, res);
});
exports.process = function(req, resp) {
var bname = req.body['date'];
if(typeof req.body['date'] !== "undefined" && req.body['date'] !== null)
{
exec_script(req, resp);
}
};

Related

Why is my Parse subscription not receiving any events (not even 'open')?

I am trying to host my parse server locally, but on my frontend I do not receive any events, not even the 'open' (connection opened) event. I also do not receive any errors that could help me solve the problem.
On my server I am using the following code:
var api = new ParseServer(
{
(... more properties and keys)
liveQuery:
{
classNames: ['Sticky', 'Canvas']
}
});
var app = express();
var mountPath = something;
app.use(mountPath, api);
var httpServer = require('http').createServer(app);
httpServer.listen(port, function(){ console.log('Running on http://localhost:' + port); });
var parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer);
On the frontend I am using the following code:
const stickyQuery = new Parse.Query(Sticky);
this.stickySubscription = await stickyQuery.subscribe();
console.log(this.stickySubscription); // This gets printed, nothing weird
this.stickySubscription.on('open', () => {
console.log('SUBSCRIPTION: opened'); // This is not printed
});
this.stickySubscription.on('create', (sticky) => {
console.log('SUBSCRIPTION: Sticky created, ', sticky); // This is also not printed
});
this.stickySubscription.on('update', (sticky) => {
console.log('SUBSCRIPTION: Sticky updated, ', sticky); // This is not printed
});
The subscription gets printed, and I don't see anything weird. It seems like connecting with the Parse server is going wrong. Does someone know what I'm missing or doing wrong?
Update: I added the following code to the frontend to show the websocket status and whether error events were triggered, but these events are also not triggered:
this.stickySubscription.on('close', () => {
console.log('SUBSCRIPTION: closed'); // This is not printed
});
Parse.LiveQuery.on('open', () => {
console.log('socket connection established'); // Gets printed
});
Parse.LiveQuery.on('close', () => {
console.log('socket connection closed'); // Is not printed
});
Parse.LiveQuery.on('error', (error) => {
console.log('socket error: ', error); // Is not printed
});
In your subscription query , write your className inside quotations:
const stickyQuery = new Parse.Query('Sticky');

PhantomJS execute javascript in <Body> tag

I am trying to scrape the below mentioned URL and trying to extract the link in the tag,using PhantomJS.
The link sends back javascript code which is executed on the browser to form the HTML inside the Body.
The problem is PhantomJS is not executing the Javascript and I am getting the unfinished HTML after executing my code.
Index.js
var page = require('webpage').create();
console.log('The default user agent is ' + page.settings.userAgent);
page.settings.userAgent = 'SpecialAgent';
page.open('http://videohost.site/play/A11QStEaNdVZfvV/', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var html = page.evaluate(function() {
return document.getElementsByTagName('body')[0].innerHTML;
});
console.log(html);
}
phantom.exit();
});
I execute it using phantomjs index.js in the console t check the HTML.
Any help regarding how would the script inside the would be executed would be much appreciated.
Update:
works with NightMareJS as according to Vaviloff's suggestion.
app.get('/scrape', function (req, res) {
//All the web scraping magic will happen here
console.log('Scrape')
url = 'http://videohost.site/play/A11QStEaNdVZfvV/'
nightmare
.goto(url)
.evaluate(function(){
return document.body.innerHTML; //pass all of the html as text
})
.end()
.then(function (document) {
console.log(document)
})
.catch(function (error) {
console.error('Search failed:', error);
})
res.send('Woohoo')
})
app.listen('8081')
console.log('Magic happens on port 8081');
exports = module.exports = app;

How to cancel a stream if browser cancels his request ? Which event

In my browser I display a lot of thumbs. If a thumb is not visible (out of the viewport), I set the src to '' (empty string). And when it is in the viewPort I set the correct src.
If the user uses his scrollbar, then the download of the thumbs that are not downloaded yet are canceled by the browser.
But on the server side, some of the requests becomes 'zombie' and can fill the sockets pool (maxSockets). After the timeout, the server will kill those sockets and the pile of un-downloaded thumbs restarts.
So I need to detect that a request is canceled by the Browser in order to end response. I tried many events, without result.
function(req, res) {
var stream;
stream = getThumb(req.file.binary.thumb);
req.on('close', function() {
return console.log("reQ.on close");
});
req.connection.on('close', function() {
return console.log('reQ.connection.on close');
});
req.on('end', function() {
return console.log('reQ.on end');
});
res.on('close', function() {
return console.log("reS.on close");
});
res.connection.on('close', function() {
return console.log('reS.connection.on close');
});
res.on('end', function() {
return console.log('reS.on end');
});
stream.on('close', function() {
return console.log('stream.on close');
});
return stream.pipe(res);
};
What is the event to listen to ?
note : I am using express, but it should make no difference.
cheers !
had similar problem, answer to this is:
req.connection.on('close', function() {
stream.destroy();
});

Socket.io connected but not communicating

I have a very simple configuration in a node server with socket.io installed (a little bit more complex but essentially like this one):
var main = require('express')();
server = require('http').createServer(main);
io = require('socket.io')(server);
io.use(function(socket, next) {
console.log("middleware!");
next();
});
io.on('connection', function (socket) {
console.log('connected...');
socket.on('pong', function (data) {
console.log(data.message);
});
setTimeout(function() {
console.log("Saying hello");
socket.emit('ping', { message: 'Hello from server ' + Date.now() });
}, 1000);
});
server.listen(2080, function onCreateServerMain() {
console.log('Server main is listening on port 2080';
console.log('************************************************************');
});
In the client:
var socketIoScript,
loadSocketTimeout,
trialsToLoadSocketIo = 0,
APP_CFG = {baseUrl : "http://192.168.1.13:2080"};
function loadSocketIo(socketIoIp) {
socketIoScript = document.createElement('script');
socketIoScript.setAttribute('src', socketIoIp);
socketIoScript.setAttribute('onload', 'onSocketLoaded();');
document.head.appendChild(socketIoScript);
}
window.onSocketLoaded = function onSocketLoaded() {
if (typeof(io.connect) === 'function') {
var mSocket,
mIoSocket;
$timeout.cancel(loadSocketTimeout);
mIoSocket = new io.Manager(APP_CFG.baseUrl);
mIoSocket.connect(function(socket) {
console.log('Connected!!');
});
mIoSocket.on('error', function onSocketError(e) {
console.log('WebSocket Error ' + error);
});
mIoSocket.on('ping', function onPingReceived(e) {
console.log('Server emitted ping: ' + e.data);
mSocket.emit('pong', 'hi server!');
});
}
}
~(function onLoadSocketTimeout() {
var nextTimeout;
if (trialsToLoadSocketIo < 10) {
nextTimeout = 5000;
} else if (trialsToLoadSocketIo > 60) {
nextTimeout = 60000;
} else {
nextTimeout = 1000 * trialsToLoadSocketIo;
}
if (socketIoScript) {
document.head.removeChild(socketIoScript);
}
loadSocketIo(APP_CFG.baseUrl + '/socket.io/socket.io.js#' + trialsToLoadSocketIo);
loadSocketTimeout = $timeout(onLoadSocketTimeout, nextTimeout);
trialsToLoadSocketIo += 1;
})();
(I'm doing like this because it's mobile app so it may have not connection). I'm testing it with Brackets and Chrome. Server and client are in the same machine. In the app the script is loaded fine and it connects to the server as I can it see in node log (edit: and this is all what I get in the node console):
Server main is listening on port 2080
************************************************************
middleware!
connected...
Saying hello
Edit: in Chrome console I don't get any message, and any breakpoint stops at on listeners. If I stop node, the console for the Chrome immediately starts logging that it has been disconnected:
GET http://192.168.1.13:2080/socket.io/?EIO=3&transport=polling&t=1413066902601-6 net::ERR_CONNECTION_REFUSED
GET http://192.168.1.13:2080/socket.io/?EIO=3&transport=polling&t=1413066906606-7 net::ERR_CONNECTION_REFUSED
But I can't see any incoming message. In the app I don't receive any incoming message. Is there any reason why I could not communicate in this environment even if socket is successfully connected?
EDIT
No app is receiving events sent from the other side. Logs from node show this, logs from Chrome are empty.
EDIT
In Chrome app I don't receive console.log("Connected!");. But neither I receive ERR_CONNECTION_REFUSED errors: I don't receive anything.
EDIT
I managed to get console.log("Connected!"); in the app by changing Manager options:
mIoSocket = new io.Manager(APP_CFG.baseUrl, { autoConnect: false });
As it was auto connecting and the events were attached after connection was made, "Connected" was never reached. But I'm still not receiving any event in any app.
I had a similar issue were event callbacks on the server were not firing when emitting. My event names were ping and pong. As soon as I renamed these events everything worked.
I suspect the event names ping and pong are reserved by socket.io and so cannot be used.
Ok, so a few things :
First, var mSocket doesn't seem to be initialized, so it may be difficult for it to emit() anything (am I missing something?)
Second, when you do :
socket.on('pong', function (data) {
console.log(data.message);
});
the server expects to receive an object containing a message property, eg : data = {message:'hi server'} In your case, you send a string, so data is 'Hi server !' and your log will say 'undefined'. You should change this bit to :
socket.on('pong', function (data) {
console.log(data);
});
and you have a similar problem the other way around, you send an object : { message: 'Hello from server ' + Date.now() }, and are trying to log a data property which does not exist. Change this bit to :
console.log('Server emitted ping: ' + e.message);
And third , you have to listen for events on the socket, not the 'manager'
Client :
mIoSocket.connect(function(socket) {
console.log('Connected!!');
socket.emit('pong');
socket.on('error', function onSocketError(e) {
console.log('WebSocket Error ' + error);
});
socket.on('ping', function onPingReceived(e) {
console.log('Server emitted ping: ' + e.data);
socket.emit('pong', 'hi server!');
});
});
Server :
io.on('connection', function (socket) {
console.log('connected...');
socket.on('pong', function (data) {
console.log(data);
});
setTimeout(function() {
console.log("Saying hello");
socket.emit('ping', { message: 'Hello from server ' + Date.now() });
}, 1000);
});

need to send error to unauthorized user in socket.io

as the title is obvoius i need to send back some error message for unauthorized user and i need to know how to achive this for example i need to send this message to user
you dont have any username to begin chat
and print it in users browser how should i do that? the client side code is something like this
//this is the client side code
var socket = io.connect('http://localhost', { resource: '/chat/app.js' });
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser')
});
socket.socket.on('error', function (reason){
console.log('Unable to connect Socket.IO', reason);
});
but the reason which i get in console is
Unable to connect Socket.IO handshake error
how should i print the message which is the cause of user is nothing get authorized?
this is the server side code
var io = require('socket.io').listen(80);
io.configure(function (){
io.set('authorization', function (handshakeData, callback) {
// findDatabyip is an async example function
findDatabyIP(handshakeData.address.address, function (err, data) {
if (err) return callback(err);
if (data.authorized) {
handshakeData.foo = 'bar';
for(var prop in data) handshakeData[prop] = data[prop];
callback(null, true);
} else {
//THIS IS THE MESSAGE *********************************************
callback('you dont have any username to begin chat', false);
}
})
});
});
To send the error back to the user you must modify the error function on manager.js (socket.io\lib\manager.js; line 768 approx) from this
function error (err) {
writeErr(500, 'handshake error');
self.log.warn('handshake error ' + err);
};
to this
function error (err) {
writeErr(500, /*'handshake error'*/ err);
self.log.warn('handshake error ' + err);
};

Resources