How to move to Socket.io v1.x from v0.9.x - node.js

I have an application under development which uses socket.io to establish Web RTC connections between multiple clients. The application was developed by another developer and I am taking it over for now. One of the things I want to do is move from socket.io v0.9.16 which is being currently used to the most up to date version v1.3.5.
I have looked at the page on migrating from v0.9 to v1.0 and tried changing a few things, however it does not seem to work for me. I am getting the following error in the chrome console:
Failed to load resource: net::ERR_CONNECTION_REFUSED https://143.167.117.93:3000/socket.io/1/?t=1435567474680
indicating that there has been a problem with the socket.io initialisation. The code below shows the way it is being done currently, which works with socket.io v0.9.16.
var protocol = require('https');
var portNo = 3000;
var app = protocol.createServer(options, function (req, res) {
/**
* server serves pages otherwise 404.html
*/
file.serve(req, res, function (err, result) {
if (err) {
console.error('Error serving %s - %s', req.url, err.message);
if (err.status === 404 || err.status === 500) {
file.serveFile(util.format('/%d.html', err.status), err.status, {}, req, res);
} else {
res.writeHead(err.status, err.headers);
res.end();
}
} else {
console.log('serving %s ', req.url);
}
});
}).listen(portNo);
var io = require('socket.io').listen(app, {
log: false,
origins: '*:*'
});
io.set('transports', [
'websocket',
'xhr-polling',
'jsonp-polling'
]);
io.sockets.on('connection', function (socket) {
//Do something
});
If you need any more information to complete this question please let me know. I have limited experience using socket.io and node.js so I apologise if the question is too broad.

Looks like you are not setting correctly socket.io and you are still using some options from socket.io 0.9 version. Try to create a basic example using socket.io migration tutorial, below it is an example of using http node.js library along with socket.io 1.x library.
app.js file:
var protocol = require('http').createServer(handler);
var file = require('fs');
var io = require('socket.io')(protocol);
var portNo = 4040;
protocol.listen(portNo, function() {
console.log('server up and running');
});
function handler(req, res) {
file.readFile(__dirname + '/index.html', function(err, data) {
if (err) {
res.writeHead(500);
return res.send('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function(socket) {
socket.emit('message', 'you just connected dude!');
});
index.html file:
<!doctype html>
<html>
<head>
</head>
<body>
<h1>Hello World</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.js">
</script>
<script>
var socket = io.connect();
socket.on('message', function(message) {
alert(message);
});
</script>
</body>
</html>

Related

unable to get data from socket.io-redis with nodejs

Hope you are doing well,
As I am creating a multiplayer games, so i need to store all user details from socket, after some time I need to make a group from the Users list.
So I tried to implement https://github.com/socketio/socket.io-redis library and trying to get all connected users but it's not working, I have developed according to this example Example to use socket.io-redis, but it'not work for me and my redis server is working well.
Thanks
Example :
index.js
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
var your_namespace_socket = io.of('/');
app.get('/', function(req, res) {
res.sendfile('index.html');
});
your_namespace_socket.on('connection', function(socket) {
console.log(socket.id);
socket.on('join', function(room) {
socket.join(room);
console.log(room);
//log other socket.io-id's in the room
your_namespace_socket.adapter.clients([room], (err, clients) => {
console.log(clients);
});
});
});
server.listen(3000, function() {
console.log('listening on *:3000');
});
index.html
<html>
<head>
<title>Hello world</title>
</head>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('/');
socket.emit('join', 'testingroom');
</script>
<body></body>
</html>
Output
User has joined session in a room with cannot fetch data from redis, as you can see in screenshot
Output of Above Code
I tested your code and it works for me, it might be an error with redis, do you have any error in the callback :
your_namespace_socket.adapter.clients([room], (err, clients) => {
if(err) console.log(err)
console.log(clients);
});

Node.js Socket.io wrong path

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.

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 example: not working

I am completely new to the socket.io and trying to get my feet wet by starting with examples on their home page. But all that i get in console after execution is this
debug - served static content /socket.io.js
My Server side code is this:
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) {
console.log("connected");
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
})
And my index.html goes like this:
var socket = io.connect('document.location.href');
socket.on('error',function(reason){
// console.error("Error");
});
socket.on('connect', function () {
console.log('connected');
socket.send('hi');
socket.on('message', function (msg) {
// my msg
});
});
</script>
I googled about it and couldn't resolve the issue. I am on ubuntu with firefox.
If i'm not mistaken your error is here:
'document.location.href'
which shall be
document.location.href
I've just complete a simple example app for which I'll be soon writing a tutorial:
https://github.com/dotcloud/socket.io-on-dotcloud
You can grab it (just clone it) and fool around with it to easy how to get started with socket.io with express 3. It is even ready to be push on dotCloud if you whish to share your app.

How to use Express post request to emit Socket.io or Sockjs?

I know this question is kind of awkward, but the problem comes from Samsung TV 2010 / 2011 SmartTV (and blue ray player; of course 2012 emulator working fine). I ported the simple chatting examples come from the source and package to SmartTV app. Both of them fall back to JSONP polling, but from SmartTV app only could emit / push to server once. Receiving the message from server could be multiple times without any problem. After looking for the answer in Samsung D forum (of course nothing there), I think the fastest way to work around this issue is to deploy an Express server, taking the post data and JSON.parse, then emit Socket.io / Sockjs internally inside the server itself.
Could anybody show me an easy sample code so I could start from there? Thanks a lot.
I quickly make code, but seems it doesn't work:
lib/server.js
var express = require('express')
, app = express.createServer()
, io = require('socket.io').listen(app);
app.listen(80);
app.use(express.bodyParser());
app.get('/', function (req, res) {
res.sendfile('/var/www/mpgs_lite_v3/index.html');
});
app.post('/', function(req, res){
console.log(req.body);
io.sockets.emit('my other event', req.body);
res.redirect('back');
});
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>
<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>
</head>
<body>
<form method="post" action="/">
<input type="hidden" name="_method" value="put" />
<input type="text" name="user[name]" />
<input type="text" name="user[email]" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
'my other event' seems not receive anything.
UPDATE: I updated the example for you to make it more complete. I didn't have an app.listen before, and here is also a client side script which shows that it, indeed, works fine:
<!doctype html>
<html>
<head>
<script src="//www.google.com/jsapi"></script>
<script src="/socket.io/socket.io.js"></script>
<script>google.load("jquery", "1.7.1")</script>
<script>
var socket = io.connect("localhost", {port: 3000});
socket.on("foo", function(message) { console.log("foo: ", message) });
$(function() {
$("button").click(function() {
$.post("/foo", { message: $("input").val() });
});
});
</script>
</head>
<body>
<input type=text>A message</input>
<button>Click me!</button>
</body>
</html>
And the server, now with an app.listen directive:
var express = require("express"),
app = express.createServer(),
io = require("socket.io").listen(app)
index = require("fs").readFileSync(__dirname + "/index.html", "utf8");
app.use(express.bodyParser());
app.get("/", function(req, res, next) {
res.send(index);
});
app.post("/foo", function(req, res, next) {
io.sockets.emit("foo", req.body);
res.send({});
});
app.listen(3000);
Usage:
node app.js
Navigate to http://localhost:3000/ and click the button. Check your console for output.
Based on SockJS express example server.js could look like:
var express = require('express');
var sockjs = require('sockjs');
// 1. Echo sockjs server
var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.2.min.js"};
var sockjs_echo = sockjs.createServer(sockjs_opts);
connections = {};
sockjs_echo.on('connection', function(conn) {
console.log(conn.id);
connections[conn.id] = conn
conn.on('close', function() {
delete connections[conn.id];
});
// Echo.
conn.on('data', function(message) {
conn.write(message);
});
});
// 2. Express server
var app = express.createServer();
sockjs_echo.installHandlers(app, {prefix:'/echo'});
console.log(' [*] Listening on 0.0.0.0:9999' );
app.listen(9999, '0.0.0.0');
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
app.post("/send", function(req, res, next) {
for(var id in connections) {
connections[id].write('received POST');
}
res.send({});
});
To test open browser at localhost:9999 and run:
curl localhost:9999/send -X POST
just remove this comment
//socket.emit('news', { hello: 'world' });
to
socket.emit('news', { hello: 'world' });
it will work because its emiting data through news and you are listening using my other event instead of 'news' or you can do just listen using 'my other event'
I don't know if this would help, but you can make an emit abstraction on the client based on your browser and then make a separate get function on the server that will handle the request the same way as the socket.on callback. In order to know where to send the information I suggest you use some key that you can store in a hash table in the server and local storage on the client.
For the client:
var emit = function(event, options) {
if ("WebSocket" in window) {
socket.emit(event, options);
console.log("emited via WebSocket");
} else {
$.post("http://localhost/emit/" + event, options);
console.log("emited via AJAX");
}
}
emit("echo", {
key: localStorage.getItem("key"),
data: {
hello: "world"
}
});
socket.on("response", function(data) {
console.log(data.hello); //will print "world"
});
For the server:
var sockets = {};
var echo_handler = function(a) {
var socket = sockets[a.key];
var data = a.data;
socket.emit("response", data);
}
app.post("/emit/:event", function(req, res) {
var event = req.params.event;
switch (event) {
case "echo":
var a = {
key: req.param("key"),
data: req.param("data")
}
echo_handler(a);
break;
}
});
io.sockets.on("connection", function(socket) {
socket.on("connect", function(data) {
sockets[data.key] = socket;
});
socket.on("echo", echo_handler);
});
Another way to do this will be to switch to Sockjs and use their patch.
If someone have better solution for Socket.IO it will be appreciated, because I'm already deep into the project and it's too late to switch Socket.IO for Sockjs, and this solution is not to my liking :( .

Resources