Socket.io is platform independent web framework which allows us to program real time bidrectional communication betweeen various devices. Using Socket.io we can build some real time application such as Live chat OR real time analytics of shares etc.
I have already covered the “event emitter” of Node.js and in this tutorial i am going to focus on covering Socket.io with simple application.
How it works ?
Socket.io is available for Node.js and also available as minified JS for client side integration so not only from Server you can emit and recieve events from Client side as well.
There are some common and most used function which you need to understand before moving ahead.
- .on : This is listener.
- .emit : This invokes and trigger the event.
For now we are using these basic function but there are more to learn ! So once the “invoker” triggers the event with some event identification particular listener or if its broadcast then every listener will catch those events and retrieve information from them.
Our application:
I am going to build simple status box which allows user to add the status and in real time update it to feeds of everyone. This is just to show how we can integrate socket.io in real time projects.
Database :
Create MySQL database name as Status and create table using following Query :
(
`status_id` INT NOT NULL AUTO_INCREMENT,
`s_text` TEXT,
`t_status` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ( `status_id` )
);
Here is our package.json.
"name" : "facebook-chat-socket",
"version" : "0.0.1",
"dependencies" : {
"express" : "~4.11.2",
"socket.io" : "~1.3.3",
"mysql" : "~2.5.5"
}
}
Install dependencies by typing
Here is main Server file.
var mysql = require("mysql");
var http = require('http').Server(app);
var io = require("socket.io")(http);
/* Creating POOL MySQL connection.*/
var pool = mysql.createPool({
connectionLimit : 100,
host : 'localhost',
user : 'root',
password : '',
database : 'fbstatus',
debug : false
});
app.get("/",function(req,res){
res.sendFile(__dirname + '/index.html');
});
/* This is auto initiated event when Client connects to Your Machien. */
io.on('connection',function(socket){
console.log("A user is connected");
socket.on('status added',function(status){
add_status(status,function(res){
if(res){
io.emit('refresh feed',status);
} else {
io.emit('error');
}
});
});
});
var add_status = function (status,callback) {
pool.getConnection(function(err,connection){
if (err) {
callback(false);
return;
}
connection.query("INSERT INTO `status` (`s_text`) VALUES ('"+status+"')",function(err,rows){
connection.release();
if(!err) {
callback(true);
}
});
connection.on('error', function(err) {
callback(false);
return;
});
});
}
http.listen(3000,function(){
console.log("Listening on 3000");
});
Here is our client side code.
<head>
<title>Socket.io</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src = "http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script>
$(document).ready(function(){
var socket = io();
$("#add_status").click(function(){
socket.emit('status added',$("#comment").val());
});
socket.on('refresh feed',function(msg){
$("#show_comments").append(msg + '<br /><br />');
});
});
</script>
</head>
<body>
<div id="comment_box" style = "padding:5%;">
<textarea id="comment" rows="5" cols="70"></textarea><br /><br />
<input type="button" id="add_status" value="Add Status">
</div>
<div
id = "show_comments"
class = "jumbotron"
style = "width: 38%;
height: 100%;
padding: 2%;
margin-left:5%;
margin-top:-53px;"
>
</div>
</body>
</html>
Output :
Run the program using
Visit “http://localhost:3000” to view the app. Open up one more window and see the updates on each window automatically.
Check the database, you can see the entries there !
Conclusion :
You can develop really cool apps using Socket.io. I am not sure though but i think Facebook comments and Twitter home page which updates the tweets as soon as someone tweet is some how related or integrated the Socket.io. Let me know if you have already built any app using this !
i want to run the code on server not localhost. how to connect to server??
“Create MySQL database name as Status and create table using following Query”. your database name is “fbstatus” not “status”.
My bad. Updated that.
Also in you index.html JavaScript it seems as if your socket is getting the status updates directly from the JavaScript on comment box button click, shouldn’t it be getting the status updates from the mysql database? Or is it telling the socketio to do a refresh and check the database for new information because a button has been clicked?
I figured out the problem, sorry I did not understand your code properly.
What was your problem? I am not able to get the page to refresh by adding a record to the database, I must click submit to get them all to refresh?
Thank you for the tutorial. If the node modules are in the root directory of my server, then why would your code reference socket.io/socket.io.js in the same directory as the index.html file? I assume because you are running in on a local machine. What would be the file path to socket.io.js? I have a dedicated linux server that I have installed node and node modules on.
Also, I don’t see where the server.js file is being referenced. Since that file has my mysql credentials in it, should I put that file in a directory outside the public_html directory, like somewhere in the root directory?
Thanks again for your tutorial.
Thank you for post but have error on server.js property “release”: >>>”C:UsersjaironoderealtimeApp>node server.js
Listening on 3000
A user is connected
A user is connected
A user is connected
C:UsersjaironoderealtimeAppnode_modulesmysqllibprotocolParser.js:82
throw err;
^
TypeError: Cannot read property ‘release’ of undefined
at C:UsersjaironoderealtimeAppserver.js:39:21
at Handshake.onConnect (C:UsersjaironoderealtimeAppnode_modulesmysqll
ibPool.js:54:9)
at Handshake.Sequence.end (C:UsersjaironoderealtimeAppnode_modulesmysq
llibprotocolsequencesSequence.js:96:24)
at Handshake.ErrorPacket (C:UsersjaironoderealtimeAppnode_modulesmysql
libprotocolsequencesHandshake.js:103:8)
at Protocol._parsePacket (C:UsersjaironoderealtimeAppnode_modulesmysql
libprotocolProtocol.js:271:23)
at Parser.write (C:UsersjaironoderealtimeAppnode_modulesmysqllibprot
ocolParser.js:77:12)
at Protocol.write (C:UsersjaironoderealtimeAppnode_modulesmysqllibpr
otocolProtocol.js:39:16)
at Socket. (C:UsersjaironoderealtimeAppnode_modulesmysqlli
bConnection.js:82:28)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
C:UsersjaironoderealtimeApp>”
breaking server and not refresh page.
Let me have a look over it.
Edit line: 13 of server.js
database : ‘Status’,
Edit line: 44 of server.js
connection.query(“INSERT INTO `fbstatus` (`s_text`) VALUES (‘”+status+”‘)”,function(err,rows){
Edit line: 23 of Server.js
database : ‘Status’,
Edit line: 44 of Server.js
connection.query(“INSERT INTO `fbstatus` (`s_text`) VALUES (‘”+status+”‘)”,function(err,rows){
How to see the mysql database in this gui like format?
As in ?
I believe that it is phpMyAdmin running here.
I have been trying various socket.io and mySQL examples with no luck in getting any of them to work. This one seem to be the easiest, but alas, I cannot get it to work at all..
I followed the example to the tee. When I browse to localhost:3000, I get:
ray@NodeJS:/node/status$ sudo node server.js
Listening on 3000
A user is connected
TypeError: Cannot call method ‘release’ of undefined
at /node/status/server.js:39:22
at Handshake.onConnect (/node/status/node_modules/mysql/lib/Pool.js:54:9)
at Handshake.Sequence.end (/node/status/node_modules/mysql/lib/protocol/sequences/Sequence.js:96:24)
at Protocol.handleNetworkError (/node/status/node_modules/mysql/lib/protocol/Protocol.js:355:14)
at PoolConnection.Connection._handleNetworkError (/node/status/node_modules/mysql/lib/Connection.js:355:18)
at Socket.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:448:13)
ray@NodeJS:/node/status$
Ideas?
Thanks
Ray
Oh my bad.
Please remove this code from line 39 and let me know.
How do I fix this:
ray@NodeJS:/node/status$ sudo node server.js
Listening on 3000
A user is connected
A user is connected
A user is connected
A user is connected
A user is connected
TypeError: Cannot call method ‘release’ of undefined
at /node/status/server.js:39:22
at Handshake.onConnect (/node/status/node_modules/mysql/lib/Pool.js:54:9)
at Handshake.Sequence.end (/node/status/node_modules/mysql/lib/protocol/sequences/Sequence.js:96:24)
at Protocol.handleNetworkError (/node/status/node_modules/mysql/lib/protocol/Protocol.js:355:14)
at PoolConnection.Connection._handleNetworkError (/node/status/node_modules/mysql/lib/Connection.js:355:18)
at Socket.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:448:13)
ray@NodeJS:/node/status$
I believe it is line 40? Anyway I already tried commenting this line out and it did not help?
Ray
It is line 39. Sorry. I had added a console.log line.
Removing it did not help.
Is this correct in the html file:
my socket.io.js script is in /node/status/node_modules/socket.io/node_modules/socket.io-client
ray@NodeJS:/node/status/node_modules/socket.io/node_modules/socket.io-client$ pwd
/node/status/node_modules/socket.io/node_modules/socket.io-client
ray@NodeJS:/node/status/node_modules/socket.io/node_modules/socket.io-client$ ls
History.md index.js lib LICENSE node_modules package.json README.md socket.io.js
I forgot to include this in the first line of my comment above:
Apparently the line I wanted to include in my comment will not show up here?
The script src=”/socket.io/socket.io.js” is not valid on my environment
So the console.log in io.on fires. I also have console.log in both of the io.on if/else cases and neither one of them are firing? So the problem appears to be somewhere in here?
io.on(‘connection’,function(socket){
console.log(“A user is connected”);
socket.on(‘status added’,function(status){
add_status(status,function(res){
Ideas?
Problem was with mysql connection which was being released on wrong place. Commenting that line in pool.getConnection() block should avoid that error. If not, can you post current error log ?
Now when I comment that line, I am getting emit error when I “Add Status”?
Ray
(Notify) Now when I comment that line, I am getting emit error when I “Add Status”?
Ray
Hi, the tutorial works well
By the way, are there anyway to update the html page everytime data changes(Update/Insert) in MySQL?
Thanks
I think this tutorial does the same!
I am not sure though but i think Facebook comments and Twitter home page which updates the tweets as soon as someone tweet is some how related or integrated the Socket.io.
C’mon dude.
https://en.wikipedia.org/wiki/WebSocket
Yeah they did and this post is just to show a small step about how they did that.
In order to provide realtime connectivity on every browser, Socket.IO selects the most capable transport at runtime, without it affecting the API. If WebSockets are available, it will use WebSockets.
If WebSockets aren’t available, Socket.IO will select the next best transport including: Adobe Flash Socket or Ajax Polling. So having a solid understanding of JavaScript Long Polling examples is crucial.
Hi. Its works well for my ubuntu droplet.
Is there possibilities to use TCP data instead of http data.?
Means, i would like to send data over TCP port 3000 & store into mysql.
Hello
I tried your example. And i have some errors.
node_modules/socket.io/socket.io.js not found. Which one is your actual socket.io.js inside node_modules.
HI, very nice tutorial. But showing status to everyone doesn’t make sense. How to control who sees the updates ?? How to control the feeds? We cannot show feeds that is not subscribed by the user…
Thanks for such a great articles ..
Keep it up…
var pool = mysql.createPool({
connectionLimit : 100,
host : ‘localhost’,
user : ‘root’,
password : ”,
database : ‘fbstatus’,
debug : false
});
how to use these lines secure ?
Can you be more specific?
in my localhost not working , just show blank status , how to fix this ?
i want upload this file on server not on xampp localhost can you please tell me how to do this ?
how about if i want my app not to open command line and listen to my localhost/app ?
Hi,
My sockets not working after page refresh.
Throwing this error in console
“Failed to load resource: net::ERR_CONNECTION_REFUSED
VM35:10 Uncaught ReferenceError: io is not defined
at HTMLDocument. (VM35:10)
at j (jquery.min.js:2)
at Object.fireWith [as resolveWith] (jquery.min.js:2)
at Function.ready (jquery.min.js:2)
at HTMLDocument.I (jquery.min.js:2)
localhost:3000/favicon.ico Failed to load resource: net::ERR_CONNECTION_REFUSED”
Please help me…
Wooow it’s cool , Thanks codeforgeek.com
how do i pull all status from db and display them in the comment section
Create an API and call it on page load.
API should select all records from the database and send it back.
Note: Won’t work for large data in production. Break it in streams.
When i click on Add Status button it do nothing, and when i refresh the page it’s shows following error!!
Listening on 3000
A user is connected
/opt/lampp/htdocs/socket-node/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/ultron/index.js:80
if (this.ee._events.hasOwnProperty(event)) {
^
TypeError: this.ee._events.hasOwnProperty is not a function
at Ultron.remove (/opt/lampp/htdocs/socket-node/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/ultron/index.js:80:27)
at Ultron.destroy (/opt/lampp/htdocs/socket-node/node_modules/socket.io/node_modules/engine.io/node_modules/ws/node_modules/ultron/index.js:116:8)
at WebSocket.cleanupWebsocketResources (/opt/lampp/htdocs/socket-node/node_modules/socket.io/node_modules/engine.io/node_modules/ws/lib/WebSocket.js:851:36)
at emitNone (events.js:91:20)
at Socket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
please do this for Mssql and C#
Great post!
A question: if I would like to call a trigger only when a value on a mysql table become 1, instead of 0? Is it possible?
Example: table “tblAlarms”. Tblalarms.alarm_1 is usually =1.
I would like to callback a function, in realtime, only when tblalarms.alarm_1 become =1. Is socket.io good to do it?
My best regards,
Alessandro
Hello Shahid,
Thanks for this content. Could you help me understand if I need to deploy this on staging or production server how to proceed with that ?
setup client and server both but showing cors origin error. tried everything but not working.
db name and table name mismatch is there in code and in the document
Any ideas?
/home/qcc/ruodai/nodejsweb/node_modules/socket.io/node_modules/debug/src/node.js:132
let val = process.env[key];
^^^
SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:374:25)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Module.require (module.js:354:17)
at require (internal/module.js:12:17)
at Object. (/home/qcc/ruodai/nodejsweb/node_modules/socket.io/node_modules/debug/src/index.js:9:19)
at Module._compile (module.js:410:26)
at Object.Module._extensions..js (module.js:417:10)
Update your Node version.
Hi, I am getting these 2 error on browser console. Not sure if I am doing anything wrong
1. GET localhost:3000/socket.io/socket.io.js 404 (Not Found)
2. Uncaught ReferenceError: io is not defined