I am trying to learn the basics of node.js and socket.io. I have been using this tutorial http://tutorialzine.com/2012/08/nodejs-drawing-game/
the full code for this problem can be seen in the link above.
I can create a basic web server with node.js and get it to return hello world so I am sure that's installed correctly. However upon installing these packages
npm install socket.io#0.9.10 node-static
and setting up the serverside js as instructed
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
nstatic = require('node-static');
var fileServer = new nstatic.Server('./');
app.listen(8080);
I just get this prompt in my cmd and a constantly hanging web browser, instead of the html page that is meant to be served.I think I may have messed up an install but upon looking at the list of installed packages in npm it states both socket.io and node-static are present.
The code below should be more effective?, it looks like you are missing the handler part. The response must be explicitly ended or browser requests will hang forever like you are seeing. The node-static file.serve method manages the request once you pass it down. The source for .serve is here: https://github.com/cloudhead/node-static/blob/master/lib/node-static.js#L164
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
nstatic = require('node-static');
app.listen(8080);
var file = new nstatic.Server('./');
function handler(request, response) {
request.addListener('end', function () {
file.serve(request, response);
}).resume();
}
console.log('started')
Note also that the default file to serve to responses at / is index.html.
Related
I am trying to create a real time chat app project using node and socket but when I try to run this using nodemon then it gives me error like
Uncaught ReferenceError: io is not defined
at client.js:1:16
and
GET http://localhost:3000/socket.io/socket.io.js net::ERR_ABORTED 404 (Not Found)
plz help me to get out from this frustration.
here are respective code:-
const express=require("express");
const http=require("http");
const app=express();
const server=http.createServer(app);
const io=require("socket.io")(server)
app.get("/",function (req,res) {
res.sendFile(__dirname+"/index.html");
})
app.use(express.static(__dirname+"/public"))
io.on("connection",(socket)=> {
console.log('Connected');
})
app.listen(process.env.PORT || 3000,function(){
console.log('Running....');
})
code at client.js:-
const socket = io()
let name;
let textarea=document.querySelector("#textarea");
let msgArea=document.querySelector(".mssg_area");
do{
name = prompt("what do your friends call you?");
}while(!name);
textarea.addEventListener("keyup",function (e) {
if(e.key==="Enter"){
sendMessage(e.target.value);
}
})
function sendMessage(message) {
let msg={
user:name,
message:message
}
appendMessage(msg,"outgoing")
}
function appendMessage(msg,type) {
let mainDiv=document.createElement("div")
let className=type
mainDiv.classList.add(className,"message")
let markUp=`
<h4>${msg.user}</h4>
<p>${msg.message}</p>
`
mainDiv.innerHTML=markUp
msgArea.appendChild(mainDiv)
}
It would be very helpful to me if you resolve this issue. Thank you in advance!!
on the client side you should install socket.io-client not socket.io
Client Api
Be sure, you have installed socket.io module. If not installed, install this by using command -
npm install socket.io
I had been fiddling around with this kind of problem for weeks. I was not able to solve this problem and it had been stressing me out. But Alas, I finally found the solution by searching in several sources. So I am going to tell the step by step process on how to fix it.
First and foremost, install the socket.io package by doing in terminal (npm install socket.io)
Second, type npm install nodemon
Third, type npm init --yto get the file package.json. Then, in the package.json, at "scripts": {}, write "devStart": "nodemon server.js" (so you don't have to re-run the code in the server) and also "start": "node server.js". Then, at "main": , type "main": "server.js"
Now, in your script.js, you forgot to put the link in io() as an argument.
For instance, you can do:
const socket = io('http://localhost:3000'); //You need to pass in the localhost:3000
let name;
let textarea=document.querySelector("#textarea");
let msgArea=document.querySelector(".mssg_area");
do{
name = prompt("what do your friends call you?");
}while(!name);
This will tell the server to access the webpage in localhost:3000
Then, in the server.js, import the module socket.io by doing:
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
which you did correctly.
But, in the last part of your code, you should do:
server.listen(process.env.PORT || 3000,function(){
console.log('Running....');
})
instead of: app.listen()
Now, this is the most confusing part. This is where the error kicks in. The reason why we get the Error:
Uncaught ReferenceError: io is not defined
at client.js:1:16
is because we haven't imported/require the module for the socket.io in the client.js. In order to do that, we first need to get the module from the node_modules folder. So:
Scroll and Find the socket.io module in the node_modules folder in VSCode ( you should see socket.io in it)
Make a new folder in your directory/folder that has your client.js and server.js called public
Then copy or move the file/module to the new folder public
Now, go to your HTML file and in the <body> type the following:
<body>
<script src="public/socket.io/client-dist/socket.io.js"></script>
<script src="client.js"></script>
</body>
Now, I might be wrong here since people do the other way that is(Doesn't work for me and probably you):
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script src="client.js"></script>
which, in my case, doesn't work for me because there is no such socket.io module in localhost/website. But, it probably doesn't work for me since I am using windows. So, if the first <script> tag I gave you didn't work, then you can try this one.
The point what I'm trying to tell you is, you need to import/require the socket.io module for the client.js in order for it to work. Otherwise, it will give that Unreferenced Error. Doing const io = require("socket.io") in client-side javascript won't work. You have to import it using <script> tag in the body. Or by doing <script defer src="..."> in the head.
So after all of this, it should work. Go to your server.js and run the server at localhost:3000. Go to Chrome(or other sites) and type localhost:3000
If the error is still there, then maybe the path to your public folder with the socket.io module is wrong OR I am wrong.
If you get the CORS error:
const io = require('socket.io')(server, {
cors: {
origin, "*" //Or type your localhost or link
methods: ["GET", "POST"]
}
});
you can go to info on socket.io Cors for more info.
Or install the cors module by doing npm install cors
Apologies if I did something wrong or for my broken English. I am terribly sorry as this is my first ever StackOverFlow answer and I couldn't just let this question go to rest. I must answer as I have the viable solution for it. So Thanks for reading this.
I'm going through this this course currently.
There is a tutorial on how to configure and run express server. The following script is suggested:
var express = require('express');
var path = require('path');
var open = require('open');
var port = 3000;
var app = express();
app.get('/',function(req, res){
res.sendFile(path.join(__dirname,'../src/index.html'));
});
app.listen(port,function(err){
if(err){
console.log(err);
}
else{
open('localhost:'+port);
}
});
When I run it in project root with $ node buildScripts/srcServer.js I get a system prompt You'll need a new app to open this localhost with the only suggestion being look at windows store.
What's that about? What does it need an app for? In the course when the script is run the browser is opened, but it's on Mac there. When I navigate manually to localhost:3000 there is the error like there is supposed to be, but I'm somewhat concerned that this behavior will mess with live reloading so I'd like to get rid of it.
Add the http:// prefix and it will open using the default browser.
open('http://localhost:'+port);
I have installed meteor library.
I want to run an angular project which has no back-end (of static content).
I want to create a server file using node.js for static content.
Is it possible to to create that and execute ?
There is a very simple example of how to create a static server in Node.js that server static content pages,
the following code is in the myserver.js file:
var http = require('http');
var finalhandler = require('finalhandler');
var serveStatic = require('serve-static');
var serve = serveStatic("./");
var server = http.createServer(function(req, res) {
var done = finalhandler(req, res);
serve(req, res, done);
});
server.listen(8000)
You need to install through NPM from command line:
$ npm install finalhandler serve-static
$ node myserver.js
It's possible with Meteor, but it's an overkill.
remove the default mongo package ($ meteor remove mongo)
put all your static files into a folder called public
You're done. This way your production build won't require a MongoDB server.
But it's a lot easier to just use the http-server NPM package to setup a static file server with Node.js.
I am working off of Yeoman's gulp-webapp generator. I have modified my gulp serve task to use my Express server, rather than the default connect server it ships with. My issue is with Livereload functionality. I am trying to simply port the connect-livereload to work with my Express server rather than having to install new dependencies. It's to my understanding that most connect middleware should work fine with Express, so I am assuming connect livereload is compatible with Express 4.
Here are the contents of the relevant tasks in my gulpfile:
gulp.task('express', function() {
var serveStatic = require('serve-static');
var app = require('./server/app');
app.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'));
app.listen(3000);
});
gulp.task('watch', ['express'], function () {
$.livereload.listen();
// watch for changes
gulp.watch([
'app/*.ejs',
'.tmp/styles/**/*.css',
'app/scripts/**/*.js',
'app/images/**/*'
]).on('change', $.livereload.changed);
gulp.watch('app/styles/**/*.css', ['styles']);
gulp.watch('bower.json', ['wiredep']);
});
gulp.task('styles', function () {
return gulp.src('app/styles/main.css')
.pipe($.autoprefixer({browsers: ['last 1 version']}))
.pipe(gulp.dest('.tmp/styles'));
});
gulp.task('serve', ['express', 'watch'], function () {
require('opn')('http://localhost:3000');
});
With this simple setup, when I run gulp serve in my cmd everything spins up fine and I can accept requests at http://localhost:3000.
Now if I go and change the body's background color from #fafafa to #f00 in main.css and hit save, my gulp output will respond with main.css was reloaded, as seen in the bottom of this screenshot.
However, my webpage does not update. The background color is still light-grey instead of red.
Is there perhaps a conflict between my express server config and the way gulp handles its files? Is my Express server forcing the use of app/styles/main.css rather than the use of .tmp/styles/main.css? Shouldn't the livereload script handle the injection of the new temporary file?
Thanks for any help.
EDIT:
I was able to move forward a bit by adding livereload.js to the script block of my index file, like so:
<script src="http://localhost:35729/livereload.js"></script>
I am now able to get live changes pushed to the client. Why was this file not getting injected before? How can I ensure this is getting used programatically as opposed to pasting it into my files?
I was able to get past this issue by removing the app.use(require('connect-livereload')({port: 35729})) from my gulpfile, along with a couple of other lines, and having that instantiate in my Express server's app.js file.
My gulpfile's express task now looks like this:
gulp.task('express', function() {
var app = require('./server/app');
app.listen(3000);
});
I added in the connect-livereload just above where I specify my static directory in Express:
if (app.get('env') === 'development') {
app.use(require('connect-livereload')());
}
app.use(express.static(path.join(__dirname, '../app')));
Once I started using this setup, I was getting the livereload.js script injected into my document, and client-side changes are now auto-refreshed just how I wanted.
Hope this helps someone!
My sio = require('socket.io').listen(app) is in my server.js file, but I'm calling a method in a library that would like to push a message to the client... say api.user.pushToClient()
How am I able to access sio.sockets from there? Perhaps my structure is incorrect?
Folder structure:
server.js
api
|--user.js
|--another.js
in server.js append this line
module.exports.sio = sio;
in api/user.js
sio = require('../server').sio;
sio.sockets.on ...
Or did I misunderstand the question?
What I understood from the question is you want to know how to use socketIO with node module.Based on my understanding you can use it as below:
First install socketIO module locally with npm by running " $npm install socket.io " command for windows.
Add Script to your HTML page:
<script src="/socket.io/socket.io.js"></script>
Now add var io = require('socket.io'); to your server or js file where you are going to use it.
Then you can have server startup code listen to that server and on connection of it perform the options for any event.
var listener = io.listen(server);
listener.sockets.on('connection', function(socket) {
socket.on('locationClick', function(data) {
// perform the function on receving locationClick event.
}
}