I am getting "io is not defined" error - node.js

I am using this on the client
<script type="text/javascript" src="http://domain.com:8440/socket.io/socket.io.js"></script>
When the server is too busy, sometimes it gives an "io not defined" error on the client. How can I resolve this ?
Here is my server code
var db_helper = require("./db.js");
var io=require('socket.io').listen(8440);
var check = require('validator').check,
sanitize = require('validator').sanitize;
var roomid=0;
var anonid;
var ilet;
var userip;
var blck_id;
io.set('transports', [
, 'xhr-polling'
, 'websocket'
, 'jsonp-polling'
]);
The server has 16 GB RAM and 13.6 GHz CPU.

Keep in mind node.js apps run in a single thread unless you're using something like Cluster to run more. This means that if you're doing something that blocks, it's possible for the requests to http://domain.com:8440/socket.io/socket.io.js to timeout, which would cause your io not defined error. You should see a 404 error in your console logs as well if / when this happens.

Try this out,
get the clientside socketio library and put it in the folder from where the js files are served. Point the script location to this file location.
You will find the client side script here
<server node_moudules>\socket.io\node_modules\socket.io-client\dist\socket.io.js
In the first place, as pointed by #Timothy try to find out why the node is getting busy.

You can try to serve the socket.io.js file from a regular web server, as Chandu pointed out.
This should at least offload the node.js server from that load.
Secondly - and this is more important - look at what is blocking your node.js server. As node.js is single threaded, you should by all means avoid long-running operations.
Can you give an example of the code you are running in node?

Related

Make a logger for Node Js

I have a project in Node Js, which executes the project on port 3000 and I access from ngrok with my browser to said localhost port, and it executes a server on port 3001 to make requests to a Maria database db. The project is done in react and the server with express.
I want to save the application logs (errors, warnings, etc.) in a log file so that I can see them whenever I want.
My intention was to use winston, and while I have no problem on the server side (3001), when I try to adapt it to the main project, I get an error that it cannot save files (the reason that appears is that it runs from the browser, and you can't create such a file because you don't have access to the project folders)
Can anyone give me some advice? Am I wrong to use winston, and should I use another?
Greetings and thanks
I've never used winston before and I couldn't find anything online about your error. In the past I've always just used node's fs module to create a log of errors and restarts.
const fs = require('fs')
Node's File System Documentation: https://nodejs.dev/learn/the-nodejs-fs-module
Short YouTube Tutorial: https://www.youtube.com/watch?v=U57kU311-nE

Socket io in node app on google app engine

I'd like to run a p2p chat written in node js with socket io on GAE.
My app works locally fine but I get error messages when I run it on the GAE servers related to the socket io I think.
Here are the two relevant script tags of my local client.html when running locally:
<script src="/socket.io/socket.io.js"></script>
<!-- <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script> -->
<script type="text/javascript">
// our socket.io code goes here
var socketio = io.connect("127.0.0.1:1337");
socketio.on("message_to_client", function (data) {
to_history(data['message']);
});
function send_message() {
var msg = [document.getElementById("text1").value, user1, uuid];
socketio.emit("message_to_server", {
message: msg
});
}
</script>
I've seen blogs/posts saying that for deployment I need to allow a firewall rule here on SO (which is in place now). I also tried pointing my deployed app to a static external IP like (after making it static in my google cloud console):
var socketio = io.connect('https://104.197.51.XXX')
or to point it to the port 65080 specified in my firewall rule (see documentation by google here:
var socketio = io.connect('https://104.197.51.XXX:65080')
None of this works.
I have the html loaded fine and the jQuery part I have and css is also loading just fine. It's just the socket stuff that I seem to be getting wrong. What do I have to change?
If this is of use, here the app.yaml:
runtime: nodejs
vm: true
Any help is greatly appreciated. Thanks.
Sadly, App Engine just doesn't support websockets (yet). The hack-around you're using is really unreliable for a few reasons:
it makes a direct connection to the instance, which can go down or be recycled at any time
Short of magic hackery, there's really no way to get https going down this route.
In short - this is not production ready. That having been said....
https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/appengine/websockets
That link will show you a working example and instructions of how to set it up.
Instead of that - I'd suggest using pubnub:
https://www.pubnub.com/docs/nodejs-javascript/pubnub-javascript-sdk
It has a really nice API, and is going to be way more reliable than anything you can hack together with App Engine (you know, until we fix this). You can see a few examples that I've done here:
https://github.com/JustinBeckwith/cloudcats/blob/master/web/public/script.js
https://github.com/JustinBeckwith/hatspin/blob/master/public/script.js
I hope this helps!
I also made the similar chat webapp recently and deployed it on heroku (https://chatterboxxx.herokuapp.com). I also used socket.io for this. I am not sure of GAE, but I don't think you need to specify any IP address in your socket.io js code.
I think you should use
var socketio = io();
instead of
var socketio = io.connect("127.0.0.1:1337");
This works well for me.

Troubleshooting socket.io error message

I inherited a project which utilizes node.js and socket.io, both of which I am not too familiar with.
I installed node.js and npm via homebrew and socket.io via npm.
The current setup has two different "sites": The frontend, that the user interacts with, and the backend that handles all the communications with a DB. The application uses several different displays, and the previous developer deemed it best to use the current setup.
I can successfully start the node server by invoking node node-server.js. In the head of the node-server.js, socket.io is being called like:
var sys = require('sys')
var exec = require('child_process').exec;
var io = require('socket.io').listen(8090);
[...]
In my front end, I call socket.io like this:
<script src="http://192.168.1.111:8090/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.111:8090');
[...]
However, when I debug the page, I get the following error messages:
SyntaxError: Unexpected identifier 'to' (anonymous function) socket.io.js:1
ReferenceError: Can't find variable: io sample.html
In the terminal window, where I started the node server, I get the output:
debug - served static content /socket.io.js
I should add that the two sites reside in separate folders - I access the frontend through a local Apache server, the piece that interacts with the DB sits someplace else on the same machine.
How would I correctly call the socket.io in my client?
Is there a way to enable better debugging?
Update
So the to in the error message, is because whenever the browser tries to load the socket.js file, it gets the reply of Welcome to socket.io

Serving Images over Websockets with NodeJS & SocketIO

I am trying to develop a very simple image server with NodeJS & SocketIO. A project I am working on requires me to load several hundred images on page-load (customer requirement). Currently, a HTTP request is made for each image via use of the HTML "img" tag. With the reduced latency and overall efficiency of websockets compared to HTTP or Ajax, I was hoping to improve performance by sending images over websockets instead.
Unfortunately, reading images from the server's file-system with NodeJS and sending them over websockets with SocketIO has been significantly slower than the traditional HTTP requests served over Apache. Below is my server code:
var express = require('express'),
app = express(),
http = require('http'),
fs = require("fs"),
mime = require('mime'),
server = http.createServer(app),
io = require('socket.io').listen(server);
server.listen(151);
io.sockets.on('connection',function(socket){
socket.emit('connected');
socket.on('getImageData',function(file,callback){
var path = 'c:/restricted_dir/'+file;
fs.readFile(path,function(err,data){
if (!err){
var prefix = "data:" + mime.lookup(path) + ";base64,";
var base64Image = prefix+data.toString('base64');
socket.emit('imageData',data,callback);
}
});
});
});
I have also tried buffering with "createReadStream", but I saw no significant speed improvements with this. I should also note that it is desirable to receive the image data as a Base64-encoded dataURI so I can simply throw that into the "src" attribute of the "img" tag. I understand Base64 means roughly a 30% increase in the data's size, but even when using binary image data, it still takes about 10 times longer than HTTP.
EDIT:
I suppose the real question here is, "are websockets really the best way to serve static files?" After further thought and additional reading, I strongly suspect the issue here is related to parallel processing. Since NodeJS operates on a single thread, maybe it is not the best solution for serving all these static image files? Does anyone have any thoughts on this?
Browsers usually open multiple connections to the same server to perform requests in parallel, and can also perform multiple requests per single connection, whereas you only have one websocket connection.
Also, the combo fs.readFile()/Base64-encode/socket.emit() introduces a significant overhead, where a regular httpd can use system calls like sendfile() and don't even have to touch the file contents before they are being sent to the client.
The single-threaded nature of Node isn't an issue here, because Node can do I/O (which is what you're doing, minus the Base64-encoding) really well.
So I would say that websockets aren't very suitable for static file serving :)

Error binding socket on heroku , not sure about using express

this is my first node.js and socket.io application , i didn't use express ,I want to deploy the application on heroku do i need to use it ? i mean i just did npm install socket.io on localhost and in my server file i.e game.js i have io = require("socket.io") and socket = io.listen(Number(process.env.PORT)) only and in one of the files where from where i am sending the message i have socket = io.connect();
so please tell me if i need to use express and how show i modify my existing application ?
I have given the link to the source of application
( https://github.com/bitgeeky/herokutest )
Although the Application works fine on localhost by changing the port no , to some port no like (8000) but Heroku error log on doing "heroku open" is http://pastebin.com/MtB0z5vQ
I noticed that you haven't created a http server. I am assuming that you are creating a web application, since you are deploying to heroku. For that, you need to create a http server in nodejs.
Go through socket.io https://github.com/LearnBoost/socket.io
Also http://socket.io/#how-to-use
This should get you started
Note: You do not need express. But it will make your work easier in many ways. Depends on the type of application that you want to create.

Resources