I am actually facing an issue here. I am having a login page From there I am going to another page. From there I am getting my socket disconnected.
What i am trying to do is
In my server side app.js
app.post('/login', urlencodedParser, function(req, res) {
req.session.username = req.body.usr;
req.session.password = req.body.pass;
req.session.password = 380;
authenticatAPI.logIn(req, res);
});
From here then to authenticate js(server side)
getUserName = req.body.usr;
getPassword = req.body.pass;
req.session.username = getUserName;
req.session.password = getPassword;
res.send({url:"screen1.html",id:100,usr:getUserName});
From here to client side
var socket = io.connect('http://localhost:8080');
When i reach here Again it goes for app.js and goes inside the io.on("connection") function ,here I am getting an error when i debug using node inspect.
"Remote debugging stopped Websocket closed reattach new target"
What should i do here....?
I'm going to bet that you have node inspect set to break on caught exceptions. Try unchecking "Pause On Caught Exceptions" near the right hand side of the debugger.
Otherwise, you are likely using a 3rd party library that is using socket.io that is throwing this error.
Related
I am on a school Chromebook, where developer tools are disabled. I sometimes coded on node.js, having server-side and client-side code. But, as developer tools are disabled, I can't check errors on the client-side, as to only find that it sometimes just stops working without a clue as to what is wrong. I have had this issue a whole lot whenever coding client-side code.
How could I detect and identify the error with only access visually to the node.js console, as well as express and socket.io?
For example,
const express=require("express");
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
app.use(
'/client',
express.static(__dirname + '/client')
);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/client/index.html');
console.log("sending site");
});
http.listen(3000, () => {
console.log('listening on *:3000 (http.listen)');
});
io.on('connection', (socket) => {
socket.emit("ERRORNOW",26);
});
//"<script src="/socket.io/socket.io.js"></script>" assumed to be in HTML file
var socket=io();
socket.on("ERRORNOW",()=>{
if("this doesnt have an ending curlybracket){
//}
//this is the error it doesnt have the ending curly bracket,
//but it doesn't show in the node.js console
//(at least on browser IDEs like repl.it),
//and debugging without the developer tools
//can be infuriating to say the least
});
The question is How can I identify a node.js client-side error on a web-based IDE without developer tools?
I have already had this issue a while ago, and due to the lack of developer tools on school Chromebooks, found the solution on my own, but I just thought that maybe I should also put it here.
My solution, as simple as it may be, is to just use a try-catch statement and send the error to the node.js console. It took a while to figure that out...
So, if you don't already have it, you would need a function that when triggered from the client side can log something into the console, inside of the io.on("connection",()=>{}); thing, like so:
io.on("connection",()=>{
socket.on("log", input=>{
console.log(input);
});
});
For example, if everything runs off of a single function that is triggered really fast (specific, but relevant to me, as I make web games), or just off of something, you can run it off of a function inside a try catch, like so:
//"<script src="/socket.io/socket.io.js"></script>" assumed to be in HTML file
var socket=io();
try{
socket.on("ERRORNOW",()=>{
try{
if("this doesnt have an ending curlybracket){
//}
}catch(error){
socket.emit("log",error);
}
});
}catch(error){
socket.emit("log",error);
}
So now, with this simple solution, you can stop commenting out 90% of your code to find that one error that makes it stop working while breaking it further by accidentally commenting out parts that help it to work in the first place!
I have a socket.io connected to a https server listening for javascript to emit information to it. I am finding that when I refresh, the socket is recording the connection - so if i console.log something in the on('connection', function(socket) { } part of the code, I will see a response in the console.
What I am finding though, is that on the server side, the socket.on() calls are not picking up anything.
So if I have a line in Javascript which is socket.emit('ping', msg), 'ping' will work on the server side for the first 9-10 refreshes, and then on the 11th refresh it will stop working - and it will stop working on all devices and all browsers. So if I open another browser and try to load it up, it won't work either.
I have checked to see if there are multiple connections building up or something like that, but I am not seeing anything. Any idea why this weird behaviour is happening?
Server Side
io.use(function(socket, next) {
// Authentication of the user is happening here - checking for cookies, sessions, etc.
}).on('connection', function(socket) {
// Setting up some variables and checking other stuff
var socketID = socket["id"];
var username = socketUsers[socketID];
locked[socketID] = {};
// Checking for the username
if(username == '' || typeof username == "undefined") {
// Emit some stuff back to Javascript
io.to(`${socketID}`).emit('criticalError', true);
return false;
}
else {
// We have a valid login, so connect to the server
++connected;
// This line will console log every time I refresh
console.log("Some text");
socket.on('ping', function(msg) {
// This line will console log for the first 9-10 refreshes, and then it suddenly stops working. Any ideas why?
console.log('Server was pinged by ' + username);
});
// This line will console log every time I refresh
console.log("Some other text");
}
});
Client side
var socket = io('https://example.com:1337');
$(document).ready(function() {
socket.emit('ping', true);
});
This is an interesting problem that you are facing. There are multiple points to check on - However the first problem I would suggest is with the below code:
var socket = io('https://example.com:1337');
$(document).ready(function() {
socket.emit('ping', true);
});
If this is the exact code on the client side, chances are that the socket.emit is getting called before the connection handshake goes through. This can be random as sometimes the document ready event might be delayed. Try setting a timeout for the emit event -
var socket = io('https://example.com:1337');
$(document).ready(function() {
setTimeout(function(){socket.emit('ping', true);},2000);
});
and give it a try. If this works, you found the problem. Next step is to ensure authentication is working correctly - Without the complete code, advising on this is difficult. Feel free to edit the question and share the code if your issue isn't resolved.
I have this simple piece of code in a server.js javascript file served by node:
function multiStep(myConnection, data) {
var i=0;
var myTimer=setInterval(function() {
if (i<data.length){
var element=JSON.stringify(data[i]);
console.log("mando elemento: "+element);
myConnection.send(element);
i++;
}
}, 3000);
}
//require our websocket library
clearInterval(myTimer);
var WebSocketServer = require('ws').Server;
//creating a websocket server at port 9090
var wss = new WebSocketServer({port: 9090});
//when a user connects to our sever
wss.on('connection', function(connection) {
loadJSON(function(response) {
//when server gets a message from a connected user
connection.on('message', function(message){
console.log("Got message from a user:", message);
});
var json = JSON.parse(response);
multiStep(connection, json, 0);
})
});
loadJSON simply loads a json data file from another web site.
When I run the client application the first time or when the timeout has ended everything goes fine. Yet if I reload the page while the timeout is not finished I get a crash when I try to use the connection of the old page on the server with report:
/var/www/html/MATERIALI/phonegap/node_modules/ws/lib/WebSocket.js:219
else throw new Error('not opened');
^ Error: not opened
at WebSocket.send (/var/www/html/MATERIALI/phonegap/node_modules/ws/lib/WebSocket.js:219:16)
at null. (/var/www/html/MATERIALI/phonegap/WebRTC/server.js:36:9)
at wrapper [as _onTimeout] (timers.js:261:14)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
As a matter of fact I could simply ignore the old session given the page is reloaded. How do I avoid the server to crash in these circumstances?
Ok, I think I found the solution; function multiStep becomes:
function multiStep(myConnection, data) {
var i=0;
clearInterval(myTimer);
myTimer=setInterval(function() {
if (i<data.length){
var element=JSON.stringify(data[i]);
console.log("mando elemento: "+element);
try {
myConnection.send(element);
console.log("mandato elemento");
} catch(err) {
console.log('Websocket error: %s', err);
}
i++;
} else {
}
}, 3000);
}
And it does not crash any longer.
You need to do some checking along the way. Your code assumes that everything is 100%.
var json = JSON.parse(response);
multiStep(connection, json, 0);
You assume there is data in response (it might be empty, or contain non-json data)
You should also check that json is a valid array before passing it to multiStep
The function multiStep also assumes that data.length will return something numeric
This may not be the complete answer, but it should give you a start on making your code more robust.
It's probably failing at myConnection.send(element); but that is probably only a symptom of your lack of checking along the way (you can also check if myConnection is still valid before you send something to it)
Referring to https://developer.mozilla.org/en-US/docs/Web/API/WebSocket, you should be able to check the myConnection.readyState value:
Ready state constants
These constants are used by the readyState attribute to describe the state of the WebSocket connection.
Constant Value Description
CONNECTING 0 The connection is not yet open.
OPEN 1 The connection is open and ready to communicate.
CLOSING 2 The connection is in the process of closing.
CLOSED 3 The connection is closed or couldn't be opened.
Your code will look like this now:
console.log("mando elemento: "+element);
if (myConnection.readyState === 1)
myConnection.send(element);
else
console.log("web socket not open");
I developed a small web application using Node.js. The core part of the server is:
var http = require('http');
var https = require("https");
var privateKey = fs.readFileSync("sslcert/server.key", "utf8");
var certificate = fs.readFileSync("sslcert/server.crt", "utf8");
var credentials = { key: privateKey, cert: certificate};
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(80);
httpsServer.listen(443);
...
var app = express();
var routes = require('./routes/index');
app.use(function https(req, res, next){
if (!req.secure) return res.redirect("https://" + req.headers.host + req.url);
next();
});
app.use('/', routes);
...
var router = express.Router();
router.get("/", function (req, res, next) {
res.render("index");
});
It works and also redirect the incoming http connections to the https server.
With Chrome for Android, sometimes (I didn't find any criteria) it doesn't load anything (i.e. no activity is shown on the server logs) or it partially loads a page - no errors though. In both case the browser shows a blank page. Refreshing multiple times ofter leads to a normal loading. In few cases I had to exit and run again Chrome.
With Firefox for Android, it always works.
I'm afraid there are some differences between browsers I'm not aware of.
Where should I look? At the Node.js server code, or in the main "index" view?
Currently I'm testing the server in LAN.
UPDATE
After debugging a bit I found that there are errors in the console when the page is not loaded (it makes sense, indeed!).
Uncaught Error: undefinedModule
at _f (https://192.168.178.53/javascripts/dojo/dojo.js:8:436)
at _16 (https://192.168.178.53/javascripts/dojo/dojo.js:8:7573)
at req (https://192.168.178.53/javascripts/dojo/dojo.js:8:555)
at _9 (https://192.168.178.53/javascripts/dojox/mobile/parser.js:11:42)
at _7.parse (https://192.168.178.53/javascripts/dojox/mobile/parser.js:102:4)
at https://192.168.178.53/:66:12
at _ce (https://192.168.178.53/javascripts/dojo/dojo.js:8:11949)
at _37 (https://192.168.178.53/javascripts/dojo/dojo.js:8:13569)
at https://192.168.178.53/javascripts/dojo/dojo.js:8:13833
at _38 (https://192.168.178.53/javascripts/dojo/dojo.js:8:13659)
and
Uncaught TypeError: Cannot read property 'set' of undefined
at https://192.168.178.53/:315:33
at _ce (https://192.168.178.53/javascripts/dojo/dojo.js:8:11949)
at _37 (https://192.168.178.53/javascripts/dojo/dojo.js:8:13569)
at https://192.168.178.53/javascripts/dojo/dojo.js:8:13833
at _38 (https://192.168.178.53/javascripts/dojo/dojo.js:8:13659)
at _81 (https://192.168.178.53/javascripts/dojo/dojo.js:8:13758)
at _f6 (https://192.168.178.53/javascripts/dojo/dojo.js:8:15537)
at HTMLScriptElement._10b (https://192.168.178.53/javascripts/dojo/dojo.js:8:18464)
The only references to my code are at line 66 and line 315.
Line 66 is just the parser invocation in the head section:
require([
"dojox/mobile/parser",
"dojox/mobile/View",
"dojox/mobile/Button",
"dojox/mobile/TextBox",
"dojox/mobile/RoundRect",
"dojox/mobile/FilteredListMixin",
"dojox/mobile/TextArea",
"dojox/mobile/Switch",
"dojox/mobile/FormLayout",
"dojox/mobile/SimpleDialog",
"dojo/domReady!"
], function (parser) {
parser.parse();
});
while line 315 is included in this short snippet, executed on startup:
var userName = JSON.parse(localStorage.getItem("userName"));
if (userName != undefined && userName.length) {
registry.byId("txtName").set("value", userName); // line 315
}
As far I as understand the console error is saying it "cannot read property (?!) set of undefined". Set is a method anyway.
I guess it doesn't find the txtName widget. It is defined as:
input#txtName.login(type="text" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="selectOnClick:true, placeHolder:'Username'" name="name" required)
and the snippet above as dojo/domReady! as last item of the require array.
It appears weird to me because FireFox doesn't throw such errors.
Do you see any evidence of wrong code here?
I am using hapijs in my MEAN stack and implemented socket.io (using this for reference: http://matt-harrison.com/using-hapi-js-with-socket-io/) Everything works fine, no problems there. It works great in my application!
However, there will be script I will be running via command line separately (which will be doing some maintenance on the application) that I was hoping to connect to the same web socket and be able to push to clients messages if data needs to be refreshed.
My index.js taken straight from the example:
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 3000 });
var io = require('socket.io')(server.listener);
io.on('connection', function (socket) {
socket.emit('Hello');
});
server.start();
I tried to create a separate JS file, and do a:
var socket = require('socket.io');
var io = socket.listen(3000);
Then passed io to send a message. This doesn't seem right... I guess I'm wondering if this can even be done. Messing around I've either created a separate web socket or no connection to the client.
Please let me know if I need to provide more information.
Thanks.
T
In your provided code, you're creating 2 servers. [io.listen()][1] listens on a port as a server.
What you need to do instead to pass messages around is to create a socket.io client in your separate script. There's a separate module for this called socket.io-client, which you can require to be a client:
client.js
var io = require('socket.io-client');
var socket = io('http://localhost:3000');
socket.on('beep', function () {
console.log('beep');
socket.emit('boop');
});
server.js
Here's a slightly updated version of your server script too (hapi v9.0.0 has a mandatory callback for server.start()):
var Hapi = require('hapi');
var server = new Hapi.Server();
server.connection({ port: 3000 });
var io = require('socket.io')(server.listener);
io.on('connection', function (socket) {
socket.emit('beep');
socket.on('boop', function () {
console.log('boop');
});
});
server.start(function () {
console.log('Started Server!');
});
If you open up a couple of terminals and run these, you should see messages passed between them and beep and boop logged out: