Node.js Socket.io wrong path - node.js

I'm experimenting this issue at game.html
GET http://localhost/socket.io/socket.io.js 404 (Not Found) game.html:1
Uncaught ReferenceError: io is not defined game.html:3
My game.html file
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost/game.html');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
And my server.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(5667);
function handler (req, res) {
fs.readFile(__dirname + '/game.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
});
It was working fine when I was using index.html instead of game.html

It looks like you're not retrieving game.html from the Node app, because the socket.io.js file seems to be retrieved from an HTTP port running on port 80 whereas your Node app is running on port 5667.
Also, your client-side connection string is incorrect:
var socket = io.connect('http://localhost/game.html');
That also tries to contact a server on port 80 (and I don't know what game.html is doing there).
So try this:
change the client-side connection string to var socket = io.connect();
start your Node app
open http://localhost:5667/ in your browser
And see if that works better.

Related

Node.js and socket.io don't work on Cloud9 IDE

Does anyone has experience to have Node.js and socket.io working on Cloud9 IDE?
The "Example (NodeJS with Socket.io)" (at https://c9.io/site/blog/2013/05/native-websockets-support/) doesn't work.
First, the server (https://c9.io/etlolap/webapp, /test.js) throws an error unless I fix as follow. I clicked Run button while test.js is on active tab.
var
socketIo = require('socket.io'),
io = socketIo.listen(Number(process.env.PORT));
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Then, my client (https://c9.io/etlolap/webapp, /test.html) still cannot connect. I clicked Preview button while test.html is on active tab.
<!doctype html>
<html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('https://webapp-c9-etlolap.c9.io');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</head>
<body>
Loading...
</body>
</html>
and got error message below.
Failed to load resource: the server responded with a status of 404 --- (Not Found) https://c9.io/socket.io/socket.io.js
Uncaught ReferenceError: io is not defined --- test.html:6
1. Steps
1.1) Run server.js
The cloud 9 console shows up:
1.2) Hit Preview on index.html
1.3) Then a window is opening on the right side of your IDE. You can either hit the button in the middle of the navigation bar or copy and paste the url into a new browser window.
1.4) Socket communication is working!
2. Prerequisite
2.1) node module socket.io
Hit F6 or View -> Console and install socket.io.
2.2) the client side JavaScript from socket.io
Since I didn't find an official link to download it, I created a GitHubGist.
socket.io.js
3. Code
server.js
// module dependencies
var http = require("http"),
sio = require("socket.io");
// create http server
var server = http.createServer().listen(process.env.PORT, process.env.IP),
// create socket server
io = sio.listen(server);
// set socket.io debugging
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
socket.emit('news', { message: 'Hello world!' });
socket.on('my other event', function (data) {
console.log(data.message);
});
});
index.html
<!DOCTYPE html>
<html>
<script src="js/socket.io.js"></script>
<script>
var socket = io.connect("https://demo-project-c9-matthiasholdorf.c9.io");
socket.on("news", function(data) {
console.log(data.message);
});
socket.emit("my other event", { message : "client emit" } );
</script>
</html>
Thanks for feedback from damphat and Matthias. After many failed attempts, finally I figured out the solution myself.
On Cloud9 IDE, the typical line in client (test.html here) has to be changed from,
<script src="/socket.io/socket.io.js"></script>
to
<script src="https://webapp-c9-etlolap.c9.io/socket.io/socket.io.js"></script>
The prefix is the URL of your Cloud9 project URL. By changing this line, my example worked.
you must flowing these step:
open the terminal on https://c9.io/etlolap/webapp, type:
npm install socket.io
node test
then open a new tab of browser with url
https://webapp-c9-etlolap.c9.io/socket.io/socket.io.js
You will see socket.io.js source code
I did not how you open test.html in c9.io without http server, did you just press preview?
Edit:
To return html files, you should merge http server and socket.io server like this:
// file: test.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen( Number( process.env.PORT ) );
function handler (req, res) {
fs.readFile(__dirname + '/test.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
To fetch any html file requested, using html files located in the file folder, you can use express:
var fs = require('fs');
var express = require('express');
var app = express();
// This fetches html files from the client folder (if they exist), and returns a "Page could not be found" error otherwise (this can be customized to some other 404 error page as desired)
app.get('*', function (req, res) {
var urlReading = req.url;
if (urlReading == "/")
{
urlReading = "/index.html";
}
urlReading = __dirname + "/client" + urlReading;
console.log("Loading: " + urlReading);
fs.readFile(urlReading, function (err, html) {
if (err) {
console.log("Could not find " + urlReading)
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end("<html><head><title>Page could not be found</title></head><body><h1>Page could not be found</h1></body></html>");
}
else
{
console.log("Found " + urlReading)
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html);
}
});
});
app.listen(process.env.PORT, process.env.IP);

Socket IO not working on other machine

I have simple socket io code
-- Server
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, 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(data);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
-- Client
<script src="http://192.168.1.100:8080/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.100:8080');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
there is no problem if the client script run on the server machine , but in other machine rather than server there is no problem in getting socket io javascript file , the client send request to server and I can see that the request received by server , but the client do not receive anything and it try to switch transport after 20 sec , none of them work. But as soon as I close server , the client receive the message that sent from server before ...
I use ubunto 12.04 LTS and Google chrome 28 , please help me through this problem

Can't find socket.io for client when server is created without handler

Browser can't find socket.io.js for client:
<script src="/socket.io/socket.io.js"></script>
When server is created without handler:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs');
app.listen(80);
//without this part:
/*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.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
I don't need and don't want handler function because everything I generate in PHP. And sometimes use client application functions for another file than index.html/php
So how to make browser can find socket.io.js?
I've wrote a demo app that you could have a look at if you don't want to loose to much time getting started with socket.io and Express 3.
To have websockets working your client js needs to be delivered from a webserver. This is one of those many browser limitation.
The easiest setup is to have a node server that provide both the client side Js and the WebSockets. Using easier the http module of Express (a bit overkill but super practical if you want to build something more than just a test app).
Other wise you need to have your client side js pointing to the right place. For example if you run your socket.io server of port 8080 and you deliver your static client side on port 8000 (using python -m SimpleHTTPServer for example or port 80 using a regular apache).
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
If you don't need access to http module functionality use this way:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Include this on your client side !
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
var io = io.connect();

NodeJS + Socket.io: client won't connect on Ubuntu server in homenetwork

I've set up a Ubuntu 10.04 server in my home network. I installed a lamp-server, NodeJs and Socket.io on it. It al seems to work fine but I can not make a connection from my client to the server. I think that I am missing the point of where to store the client files and/or how to the IP adress and port should be put in the code.
I'm using the example from David Walsh (http://davidwalsh.name/websocket). My ip-adress of the server is 192.168.1.113. On the client I store app.js in
/usr/local/bin
That is where node is installed as wel.
Server code
// Require HTTP module (to start server) and Socket.IO
var http = require('http'), io = require('socket.io');
// Start the server at port 8000
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(8000);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});
When I start the server with Node and enter the adress in a browser (http://192.168.1.113:8000) I see 'Hello Socket Lover!' so I guess this works fine.
I store my client file (client.html) in
/var/www
That is where the home folder of my LAMP server is.
Client.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script>
// Create SocketIO instance, connect
var socket = new io.Socket('http://192.168.1.113',{
port: 8000
});
socket.connect();
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
}
</body>
</html>
Now when I open this file in a browser (http://192.168.1.113/client.html) nothing happens. I see no connection on my Ubuntu server or other logs and there are no messages in the browser.
Ehmm... what am I doing wrong? I've tried for hours, changing all kind of things but still no result.
With the help of pmavik (see comments) my question is answered.
What I didn't know was how to serve the client file properly (index.html). I copied an example from www.socket.io, added the right ip-adress and port and now a connection is made.
The server file (app.js) and the client file (index.html) should be in the directory where Node is installed. The Node-server sends the client file to the browser so there is no need to put the client file in the /var/www directory where the 'normal' files for websites are.
app.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8000);
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.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
index.html
<html>
<head></head>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.113:8000');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
</body>
</html>

Separating file server and socket.io logic in node.js

I'm fairly new to node.js and I've found its quite complicated separating a project into multiple files as the project grows in size. I had one large file before which served as both a file server and a Socket.IO server for a multiplayer HTML5 game. I ideally want to separate the file server, socket.IO logic (reading information from the network and writing it to a buffer with a timestamp, then emitting it to all other players), and game logic.
Using the first example from socket.io to demonstrate my problem, there are two files normally. app.js is the server and index.html is sent to the client.
app.js:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, 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.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
index.html:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
To separate file server and game server logic I would need the function "handler" defined in one file, I would need the anonymous function used a callback for io.sockets.on() to be in another file, and I would need yet a third file to successfully include both of these files. For now I have tried the following:
start.js:
var fileserver = require('./fileserver.js').start()
, gameserver = require('./gameserver.js').start(fileserver);
fileserver.js:
var app = require('http').createServer(handler),
fs = require('fs');
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);
});
}
module.exports = {
start: function() {
app.listen(80);
return app;
}
}
gameserver:
var io = require('socket.io');
function handler(socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
}
module.exports = {
start: function(fileserver) {
io.listen(fileserver).on('connection', handler);
}
}
This seems to work (the static content is properly served and the console clearly shows a handshake with Socket.IO when the client connects) although no data is ever sent. It's as though socket.emit() and socket.on() are never actually called. I even modified handler() in gameserver.js to add console.log('User connected'); however this is never displayed.
How can I have Socket.IO in one file, a file server in another, and still expect both to operate correctly?
In socket.io 0.8, you should attach events using io.sockets.on('...'), unless you're using namespaces, you seem to be missing the sockets part:
io.listen(fileserver).sockets.on('connection', handler)
It's probably better to avoid chaining it that way (you might want to use the io object later). The way I'm doing this right now:
// sockets.js
var socketio = require('socket.io')
module.exports.listen = function(app){
io = socketio.listen(app)
users = io.of('/users')
users.on('connection', function(socket){
socket.on ...
})
return io
}
Then after creating the server app:
// main.js
var io = require('./lib/sockets').listen(app)
i would do something like this.
app.js
var app = require('http').createServer(handler),
sockets = require('./sockets'),
fs = require('fs');
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);
});
}
sockets.startSocketServer(app);
app.listen(80);
and sockets.js
var socketio = require('socket.io'),
io, clients = {};
module.exports = {
startSocketServer: function (app) {
io = socketio.listen(app);
// configure
io.configure('development', function () {
//io.set('transports', ['websocket', 'xhr-polling']);
//io.enable('log');
});
io.configure('production', function () {
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // apply etag caching logic based on version number
io.set('log level', 1); // reduce logging
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
});
//
io.sockets.on('connection', function (socket) {
console.log("new connection: " + socket.id);
socket.on('disconnect', function () {
console.log("device disconnected");
});
socket.on('connect_device', function (data, fn) {
console.log("data from connected device: " + data);
for (var col in data) {
console.log(col + " => " + data[col]);
}
});
});
}
};
i just copy&pasted some of my old code - don't really know what changed in the last versions of socket.io, but this is more about the structure than the actual code.
and i would only use 2 files for your purposes, not 3.
when you think about splitting it up further, maybe one other file for different routes ...
hope this helps.
I have had a crack at this as well and I am fairly happy with the result. Check out https://github.com/hackify/hackify-server for source code.
I've another solution. You can use require.js creating a module and pass "app" as an argument. Within the module you can start socket.io and organize your sockets.
app.js:
var requirejs = require('requirejs');
requirejs.config({
baseUrl: './',
nodeRequire: require
});
requirejs(['sockets'], function(sockets) {
var app = require('http').createServer()
, fs = require('fs')
, io = sockets(app);
// do something
// add more sockets here using "io" resource
});
In your socket.js module you can do something like this:
define(['socket.io'], function(socket){
return function(app){
var server = app.listen(3000)
, io = socket.listen(server);
io.sockets.on('connection', function (socket) {
console.log('connected to socket');
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
// more more more
});
return io;
}
});
I hope help you with my contribution.

Resources