First of all i've done some tutorials like:
https://socket.io/docs/
&
http://www.programwitherik.com/getting-started-with-socket-io-node-js-and-express/
&
a chat tutorial which i closed already so no link there.
But for all of them its the same. The Folder node_modules exists, the server is running (named app.js or index.js) and the index.html opens. But in every version and every test i dont get it to communicate from client to server. In one of these many questions here wrote someone about a funny installation path. So could it be that something is missing or installed in the wrong folder, needs extra permission or something like that?!
I also installed nodejs new, setup a path like others did in users/apps/ but also the same problems. Where could i find out what went wrong?! Is there a way to trace if the server got all files at the right point?!
The codes are verry basic, just hello world stuff. So i wonder why this wont work.
EDIT:
There is no very special code to share with you. Its the basic!
Server (app.js)
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client (index.html)
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
And in my case just for this one sample from the socket.io docs its the port. If i change it to 1337 it would refuse the connection. (just testing with crome without any changes in the browser or something like that) I will also test things like
var socket = io();
and many other things i read while searching about the solution. So maybe it helps other guys while they follow steps in tutorials where the port was changed without making it usable or open it. I think that was all the time the problem.
Im courious about how others have managed it, while writing a doc or tutorial about it but not one was going to tell that it could not work when there is something wrong with the port. Anyway, i'll update this with an edit2 - 3 and so on for the other tutorials i've made and will add also how it works with other ports, if nobody else do it here.
EDIT 2:
Works also perfectly fine now:
var socket = io();
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
and also
<script src="/socket.io/socket.io.js"></script>
Folders also work now:
Without
res.sendFile(__dirname + '/index.html');
/app
|- app.js
|- index.js
|node_modules
||- socket.io
||- express
also
res.sendFile(__dirname + '/client/index.html');
/app
|- app.js
|node_modules
||- socket.io
||- express
|client
||- assets
||- img
||- js
|server
||- js
Thanks to all who wanted to help.
Related
As a javascript newbie, I want to create a front-end project with a very little backend solution using Node.js.
I have a user inteface with some variables and a button. These variables have to be passed to a simple .txt file(on my filesystem) and overwrite its content. For this, I'm using a nodejs script:
var fs = require('fs');
fs.writeFile('log.txt', 'This is my text', function (err) {
if (err) throw err;
console.log('Replaced!');
});
But I want this to work onClick, whereas this only works from the command-line.
So I have the two following problems:
I want to update the .txt file with the button click. So basically the above written code has to be executed, when I click the button. But I don't understand, how to connect the front-end with this nodejs file.
I want the content to be dynamical. I'm sure, once the first problem is solved, this will be straightforward, but right now I don't know this either.
I'm 100% sure I'm missing something(maybe a web-server, but even then, how?). I did my research but all I found was either an overkill or I didn't even understand it. Any help would be appreciated, a tutorial, an advice or just a keyword, that I can use for my research.
Have a look at express. It's a "Fast, unopinionated, minimalist web framework for node". With this you can build a small webserver:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
});
app.listen(3000); // Webserver is running on port 3000
If you run it and got to your browser on http://localhost:3000, it would print Hello World.
Now what you would do is calling your logging function every time a specific URL is requested.
var fs = require('fs');
function log(text, callback) {
fs.writeFile('log.txt', text, callback);
}
app.get('/', function (req, res) {
log('This is my text', function (err) {
if (err) throw err;
res.send('Replaced!');
});
});
Now when you click the button you need to make an AJAX request to the server (maybe using jQuery).
Node.js doesnt have a built in front-library like some other scripting languages such as Python or VB. To create a node.js your intuition was correct in that you will need your app to expose itself as a web-server.
The popular library to do this is called express and it is very easy to get started.
I suggest that you follow the express quickstart tutorial to get into it.
From here you can wrap your code inside a route of the webserver (say /save) for example
var fs = require('fs');
var express = require('express');
var app = express();
app.get('/save', function (req, res) {
fs.writeFile('log.txt', 'This is my text', function (err) {
if (err) throw err;
console.log('Replaced!');
res.send('Replaced!')
});
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
With this example with the dependencies installed opening localhost:3000/save in your browser would cause your code to be run.
var app = require("http").createServer(handler); // handler defined below
var io = require("socket.io")(app);
var fs = require('fs');
app.listen(8080);
function handler (req, res) {
fs.readFile(__dirname + "/index.html",
function (err, data) {
if (err) {
res.writeHead(500);
return res.end("Error loading index.html");
}
res.writeHead(200);
res.end("Hell World");
});
}
io.on('connection', function(socket){
socket.on('dataChanged', function(data){console.log("Hello World")});
})
io.emit('dataChanged', 'this is a test')
//index.html
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('dataChanged', function(data){console.log("Hello World")});
</script>
I am trying to implement this trivial feature but it is not working.Where am i going wrong i dont see the logs. socket events are not registered.
Alright three things here.
1. Your res.end is sending Hell world but it should send data
res.end("Hell World");
should be
res.end(data);
This is because we want to display the index.html file not a hello world
2. Your index.html is calling the socket.io js file wrong
<script src="/node_modules/socket.io/socket.io.js"></script>
should be
<script src="/socket.io/socket.io.js"></script>
This is because you cannot reference a file like that because there is no logic for it in your code. socket.io does however have the logic for it and can be called this way
3. Use emit on the client side
In your index.html change this code
socket.on('dataChanged', function(data){console.log("Hello World")});
to
socket.emit('dataChanged', 'this is a test')
and remove
io.emit('dataChanged', 'this is a test')
from your nodejs file
Now you can see Hello World from your console
When I was trying to create a simple chat using socket.io I had a conneciton problem, I assume that you have the same problem: I've used the same io.connect('http://localhost:8080') but later I tried using the IP address of my computer in WiFi network to connect from other devices (because localhost points to current device) - so the IP address of my computer in WiFi network was 192.168.0.103 -> io.connect('http://192.168.0.103') or io.connect('http://192.168.1.103'). I hope this works (the code was for Front-End side).
As I am a newbie to Node.js and is learning from different articles. So, far I have learnt, my code is
At server side with app.js
var http = require('http');
var app = http.createServer(function(req,res)
{
req.on('end',function()
{
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello');
});
});
var io = require('socket.io').listen(app);
io.sockets.on('connection',function(socket)
{
socket.emit('connect',{msg:'Hello Client'});
socket.on('client_Says',console.log);
});
app.listen(3000);
At client side with index.html
<script type="text/javascript" src="//localhost:3000/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect('//localhost:3000');
socket.on('connect',function(data)
{
alert('Server says '+data.msg);
socket.emit('client_Says',{data:'Hello Server'});
});
</script>
What is that I am doing wrong in above code? When I run app.js in console, it says info - socket.io started but when I run http://localhost:3000 it just keep requesting server.
plus I want to know that is it true that wherever on my pc I create my folder for Node and place app.js and index.html files like above in it and run http://localhost:3000 in browser will automatically make that folder my site folder for localhost after running app.js in Node console?
In your app.js update code to this
var http = require('http'),
fs = require('fs'), //<--- File Module
index = fs.readFileSync(__dirname + '/index.html');
var app = http.createServer(function(req,res)
{
res.writeHead(200, {'Content-Type': 'text/html'}); //<-Updated to text/html
res.end(index); //<---I am sending page
});
Hope that solves your problem
You're not supposed to do this on server side:
socket.emit('connect',{msg:'Hello Client'});
because connect is a default event which is emitted on a successful connection from the server. So when a client connects, the server fires its default 'connect' event, but here you're also triggering your event named connect which might be causing problem.
I have the following simple JS file, which will look familiar to anyone who's used Socket.IO with NodeJS and the Express framework:
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
server.listen(8374);
// routing
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
In index.html, I have the following line of code:
<script src="/socket.io/socket.io.js"></script>
I have done some experimenting with pathnames and serving/mounting and I still don't really understand how this client-side line manages to work. The answer to this question says that by listening to the server, io handles all incoming Socket.IO requests.
...
My question is: Can this be done for other client-side JS files?
For example, is there some easy way to bundle up JQuery so that it can be handled in the same way? At the moment I can put the file in a folder like public and use Express' app.use() method so that in index.html I can include this line:
<script src="/public/jquery-1.9.1.js"></script>
Is there a way to manage JQuery as a dependency as we can with NodeJS?
I'm thinking the end result would look something like this:
SERVER-SIDE:
var jquery = require('jquery');
CLIENT-SIDE:
<script src="jquery/jquery-1.9.1.js"></script>
I'm not too sure about using modules to host specific files, but it would be more time-efficient to just host the file when it's requested:
app.get("/", function (req, res) {
res.sendfile(__dirname + "/index.html");
});
app.get("/public/jquery-1.9.1.js", function (req, res) {
res.sendfile(__dirname + "/public/jquery-1.9.1.js");
});
I don't use Express, so please excuse any mistakes.
In express 2.x many used to use "dynamicHelpers" for this. Something like this in your app.js
app.dynamicHelpers({
scripts: function (){
return ['/js/jquery.min.js', '/js/jquery.ui.min.js']
}
})
In your layout using jade you'd do this.
- each s in scripts
script(type='text/javascript', src= s)
Now app.dynamicHelpers has been removed so in express 3.x you'll need to either create a simple module for this or just do it inline. with app.use within your configuration or specific environment if need be. something like.
app.use(function (req, res, next){
res.locals.scripts = ['/js/yourscript.js', '/js/yourotherscript.js']
next();
}
Using it in the jade layout would be the same. If I'm understanding you correctly that would be one way to include these scripts. Personally I'd rather included them statically though.
I am using socket.io for a windows azure project. Strangely the socket.io server starts when i just deploy the web role but when i deploy the whole cloud project, the socket.io server doesnt start and i get this error -
"SCRIPT7002: XMLHttpRequest: Network Error 0x2efd, Could not complete the operation due to error 00002efd."
I have absolutely no idea what that means. Can anyone help me out on this one? I have been banging my head about it all day.
SocketClient.html
<script>
var socket = io.connect('http://127.0.0.1:4001');
socket.on('news', function (data) {
console.log(data);
});
$(function () {
$("#sendresponse").bind("click", function () {
socket.emit('server', 'Hello World');
});
}
);
</script>
App.js
var app = require('express')(), server = require('http').createServer(app), io = require('socket.io').listen(server);
server.listen(4001);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'first time connect' });
socket.on('server', function (data) {
console.log(data);
socket.emit('news',"hello");
});
});
Turned out that the App.js script was not running when i deployed the cloud project, i.e the iisnode handler which i had put in my web.config wasnt doing its job when the whole cloud project was deployed. After going through this article i found out that i had to put some files in my bin folder of web role namely - ChangeConfig.ps1,download.ps1,node.cmd,setup_web.cmd. you can generate these files when you go through that article. And finally you have to put this code in your ServiceDefinition.csdef
<Startup>
<Task commandLine="setup_web.cmd > log.txt" executionContext="elevated">
<Environment>
<Variable name="EMULATED">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/#emulated" />
</Variable>
<Variable name="RUNTIMEID" value="node;iisnode" />
<Variable name="RUNTIMEURL" value="" />
</Environment>
</Task>
</Startup>
And voila!! It works like a charm. You would still have to start the socket.io server by running 127.0.0.1/App.js on browser. I am still looking at how to start App.js programattically.