Socket.IO is JavaScript implementation to work with HTML 5 WebSockets. In can be used in NodeJS & based server frameworks for server-side, while client-side can be integrated with pure JavaScript, AngularJS, React.
Socket.IO proves to be promising with over 49K GitHub Stars . Furthermore it’s stable for production level with V2.0.0 being released in 2017.
Quick links Documentation
NPM Version
Node Version
0. Installing Packages
Installing Packages
npm i --save express nodemon socket.io
What is Express Express.js, or simply Express, is a web application framework for Node.js, released as free and open-source software under the MIT License. It is designed for building web applications and APIs. It has been called the de facto standard server framework for Node.js. en.wikipedia.org
What is Nodemon Nodemon is a development dependency that monitors for any changes in your Node. js application and automatically restarts the server, saving time and tedious work. medium.com
What is Socket.io Socket.IO is JavaScript implementation to work with HTML 5 WebSockets. In can be used in NodeJS & based server frameworks for server-side, while client-side can be integrated with pure JavaScript, AngularJS, React.Socket.io
npm i --save-dev babel-cli babel-preset-env babel-preset-stage-0
In package.json file add these lines in the script keyword
// package.json
"scripts" : {
"start" : "nodemon ./index.js --exec babel-node -e js" ,
"test" : "DEBUG=* npm run nodemon ./index.js --exec babel-node -e js"
} ,
Create a new file .babelrc with the same directory of package.json file.
Hint
Insert the following snippet into the newly created file.
{
"presets" : [
"env" ,
"stage-0"
]
}
Hint
Babel is used to compile the project
1. Simple chat app
Create a file index.js on the same level of node_modules directory and paste the following snipet into it.
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
io . on ( 'connection' , ( socket ) => {
console . log ( 'user connected' );
socket . emit ( 'message' , { manny : 'hey how are you?' });
socket . on ( 'another event' , ( data ) => {
console . log ( data );
})
})
Now create a directory public on the same level of node_modules directory.
Create a file index.html and paste the below snippet into it.
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<! DOCTYPE html >
< html lang = "en" >
< head >
< title >< /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< /head>
< body >
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const socket = io . connect ( 'http://localhost:3000' );
socket . on ( 'message' , ( data ) => {
console . log ( data );
socket . emit ( 'another event' , { jeremy : 'I am great thank you' });
})
< /script>
< /body>
< /html
[nodemon] app crashed - waiting for file changes before starting... Node.JS: Getting error : [nodemon] Internal watch failed: watch ENOSPC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16events.js:183
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE :::3000
at Object._errnoException (util.js:1022:11)
at _exceptionWithHostPort (util.js:1044:20)
at Server.setupListenHandle [as _listen2] (net.js:1367:14)
at listenInCluster (net.js:1408:12)
at Server.listen (net.js:1492:7)
at Object.<anonymous> (/home/mohsin/Desktop/chatter02/index.js:6:8)
at Module._compile (module.js:652:30)
at loader (/home/mohsin/Desktop/chatter02/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/home/mohsin/Desktop/chatter02/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:565:32)
[nodemon] app crashed - waiting for file changes before starting...
Solution to this problem is in the following snippet
echo fs.inotify.max_user_watches= 524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
or
There is a server that's already running, so you cannot start another server.
Now, with Bootstrap
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
io . on ( 'connection' , ( socket ) => {
console . log ( 'user connected' );
socket . on ( 'message' , ( msg ) => {
console . log ( `message: ${ msg } ` );
io . emit ( 'message' , msg );
})
})
and the index.html (client) should look like this —
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const socket = io ();
$ ( 'form' ). submit (() => {
socket . emit ( 'message' , $ ( '#m' ). val ());
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
2. Connect / Disconnect Events
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
io . on ( 'connection' , ( socket ) => {
console . log ( 'user connected' );
socket . on ( 'message' , ( msg ) => {
console . log ( `message: ${ msg } ` );
io . emit ( 'message' , msg );
});
socket . on ( 'disconnect' , () => {
console . log ( 'user disconnected' );
io . emit ( 'message' , 'user disconnected' );
})
})
and the index.html (client) should look like this —
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const socket = io ();
$ ( 'form' ). submit (() => {
socket . emit ( 'message' , $ ( '#m' ). val ());
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'message' , 'user connected' );
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
3. NameSpace Setup
Now, we are going to add a namespace tech to our server.
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
// tech namespace
const tech = io . of ( '/tech' );
tech . on ( 'connection' , ( socket ) => {
console . log ( 'user connected' );
socket . on ( 'message' , ( msg ) => {
console . log ( `message: ${ msg } ` );
tech . emit ( 'message' , msg );
});
socket . on ( 'disconnect' , () => {
console . log ( 'user disconnected' );
tech . emit ( 'message' , 'user disconnected' );
})
})
and the index.html (client) should look like this —
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const socket = io ( '/tech' );
$ ( 'form' ). submit (() => {
socket . emit ( 'message' , $ ( '#m' ). val ());
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'message' , 'user connected' );
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
4. Setting up Rooms
Init Room Javascript
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
// tech namespace
const tech = io . of ( '/tech' );
tech . on ( 'connection' , ( socket ) => {
socket . on ( 'join' , ( data ) => {
socket . join ( data . room );
tech . in ( data . room ). emit ( 'message' , `New user joined ${ data . room } room!` );
})
socket . on ( 'message' , ( data ) => {
console . log ( `message: ${ data . msg } ` );
tech . in ( data . room ). emit ( 'message' , data . msg );
});
socket . on ( 'disconnect' , () => {
console . log ( 'user disconnected' );
tech . emit ( 'message' , 'user disconnected' );
})
})
and the index.html (client) should look like this —
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const room = 'javascript' ;
const socket = io ( '/tech' );
$ ( 'form' ). submit (() => {
let msg = $ ( '#m' ). val ();
socket . emit ( 'message' , { msg , room });
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'join' , { room : room });
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
**JavaScript Room with seperate base file **
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
app . get ( '/javascript' , ( req , res ) => {
res . sendFile ( __dirname + '/public/javascript.html' );
});
// tech namespace
const tech = io . of ( '/tech' );
tech . on ( 'connection' , ( socket ) => {
socket . on ( 'join' , ( data ) => {
socket . join ( data . room );
tech . in ( data . room ). emit ( 'message' , `New user joined ${ data . room } room!` );
})
socket . on ( 'message' , ( data ) => {
console . log ( `message: ${ data . msg } ` );
tech . in ( data . room ). emit ( 'message' , data . msg );
});
socket . on ( 'disconnect' , () => {
console . log ( 'user disconnected' );
tech . emit ( 'message' , 'user disconnected' );
})
})
and the index.html (client) should look like this —
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< /head>
< body >
< div class = "jumbotron jumbotron-fluid" >
< div class = "container" >
< h1 class = "display-3" > Tech space chatter < /h1>
< p class = "lead" > Select which room you ' d like to join below !!!< /p>
< /div>
< /div>
< div class = "container-fluid" >
< div class = "row" >
< ul class = "list-group col" >
< a href = "/javascript" class = "list-group-item list-group-item-action" > Javascript < /a>
< a href = "#" class = "list-group-item" > Swift < /a>
< a href = "#" class = "list-group-item" > CSS < /a>
< /ul>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< /body>
< /html
javascript.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const room = 'javascript' ;
const socket = io ( '/tech' );
$ ( 'form' ). submit (() => {
let msg = $ ( '#m' ). val ();
socket . emit ( 'message' , { msg , room });
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'join' , { room : room });
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
5. Complete tech rooms
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43const app = require ( 'express' )();
const server = require ( 'http' ). Server ( app );
const io = require ( 'socket.io' )( server );
const port = 3000 ;
server . listen ( port , () => {
console . log ( `Server is running on port ${ port } ` );
});
app . get ( '/' , ( req , res ) => {
res . sendFile ( __dirname + '/public/index.html' );
});
app . get ( '/javascript' , ( req , res ) => {
res . sendFile ( __dirname + '/public/javascript.html' );
});
app . get ( '/swift' , ( req , res ) => {
res . sendFile ( __dirname + '/public/swift.html' );
});
app . get ( '/css' , ( req , res ) => {
res . sendFile ( __dirname + '/public/css.html' );
});
// tech namespace
const tech = io . of ( '/tech' );
tech . on ( 'connection' , ( socket ) => {
socket . on ( 'join' , ( data ) => {
socket . join ( data . room );
tech . in ( data . room ). emit ( 'message' , `New user joined ${ data . room } room!` );
})
socket . on ( 'message' , ( data ) => {
console . log ( `message: ${ data . msg } ` );
tech . in ( data . room ). emit ( 'message' , data . msg );
});
socket . on ( 'disconnect' , () => {
console . log ( 'user disconnected' );
tech . emit ( 'message' , 'user disconnected' );
})
}
and the index.html (client) should look like this —
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< /head>
< body >
< div class = "jumbotron jumbotron-fluid" >
< div class = "container" >
< h1 class = "display-3" > Tech space chatter < /h1>
< p class = "lead" > Select which room you ' d like to join below !!!< /p>
< /div>
< /div>
< div class = "container-fluid" >
< div class = "row" >
< ul class = "list-group col" >
< a href = "/javascript" class = "list-group-item list-group-item-action" > Javascript < /a>
< a href = "/swift" class = "list-group-item" > Swift < /a>
< a href = "/css" class = "list-group-item" > CSS < /a>
< /ul>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< /body>
< /html
javascript.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter / Javascript < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const room = 'javascript' ;
const socket = io ( '/tech' );
$ ( 'form' ). submit (() => {
let msg = $ ( '#m' ). val ();
socket . emit ( 'message' , { msg , room });
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'join' , { room : room });
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
swift.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter / Swift < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const room = 'swift' ;
const socket = io ( '/tech' );
$ ( 'form' ). submit (() => {
let msg = $ ( '#m' ). val ();
socket . emit ( 'message' , { msg , room });
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'join' , { room : room });
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
css.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57<! DOCTYPE html >
< html lang = "en" >
< head >
< title > Chatter / CSS < /title>
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< style >
form { padding : 20 px ; position : fixed ; bottom : 0 ; width : 100 % ; padding - right : 50 px ;}
# messages { list - style - type : none ; margin : 0 ; padding : 0 ; width : 100 % ;}
# messages li { padding : 5 px 10 px ; }
# messages li : nth - child ( odd ) { background : # eee ;}
< /style>
< /head>
< body >
< div class = "container-fluid" >
< div class = "row" >
< ul id = "messages" >< /ul>
< /div>
< div class = "row" >
< div class = "col-lg-6" >
< form action = "" >
< div class = "input-group" >
< input id = "m" autocomplete = "off" type = "text" class = "form-control" placeholder = "Message..." aria - label = "Message..." >
< span class = "input-group-btn" >
< button class = "btn btn-secondary" type = "submit" > Send < /button>
< /span>
< /div>
< /form>
< /div>
< /div>
< /div>
< script src = "https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity = "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< script >
const room = 'css' ;
const socket = io ( '/tech' );
$ ( 'form' ). submit (() => {
let msg = $ ( '#m' ). val ();
socket . emit ( 'message' , { msg , room });
$ ( '#m' ). val ( '' );
return false ;
});
socket . on ( 'connect' , () => {
// emiting to everybody
socket . emit ( 'join' , { room : room });
})
socket . on ( 'message' , ( msg ) => {
$ ( '#messages' ). append ( $ ( '<li>' ). text ( msg ));
})
< /script>
< /body>
< /html
6. Chat App Demo
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32var express = require ( 'express' )
var bodyParser = require ( 'body-parser' )
var app = express ()
var http = require ( 'http' ). Server ( app )
var io = require ( 'socket.io' )( http )
app . use ( express . static ( __dirname ))
app . use ( bodyParser . json ())
app . use ( bodyParser . urlencoded ({ extended : false }))
var messages = [
{ name : 'Mohsin' , message : 'Hi' },
{ name : 'Mahmood' , message : 'Hello' }
]
app . get ( '/messages' , ( req , res ) =>{
res . send ( messages )
})
app . post ( '/messages' , ( req , res ) =>{
messages . push ( req . body )
io . emit ( 'message' , req . body )
res . sendStatus ( 200 )
})
io . on ( 'connection' , ( socket ) => {
console . log ( 'a user connected' )
})
var server = http . listen ( 3000 , () => {
console . log ( 'server is listening on port' , server . address (). port )
}
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48<! doctype html >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity = "sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin = "anonymous" >
< script src = "https://code.jquery.com/jquery-3.2.1.min.js" crossorigin = "anonymous" >< /script>
< script src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity = "sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin = "anonymous" >< /script>
< script src = "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity = "sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin = "anonymous" >< /script>
< script src = "/socket.io/socket.io.js" >< /script>
< div class = "container" >
< br >
< div class = "jumbotron" >
< h1 class = "display-4" > Send Message < /h1>
< br >
< input id = "name" class = "form-control" placeholder = "Name" >
< br >
< textarea id = "message" class = "form-control" placeholder = "Message" >< /textarea>
< br >
< button id = "send" class = "btn btn-success" > Send < /button>
< /div>
< div id = "messages" >
< /div>
< /div>
< script >
var socket = io ()
$ (() => {
$ ( "#send" ). click (()=>{
var message = { name : $ ( "#name" ). val (), message : $ ( "#message" ). val ()}
postMessage ( message )
})
getMessages ()
})
socket . on ( 'message' , addMessage )
function addMessage ( message ){
$ ( "#messages" ). append ( `<h4> ${ message . name } </h4> <p> ${ message . message } </p>` )
}
function getMessages () {
$ . get ( 'http://localhost:3000/messages' , ( data ) => {
data . forEach ( addMessage );
})
}
function postMessage ( message ) {
$ . post ( 'http://localhost:3000/messages' , message )
}
< /script
Manually
For Linux
For Windows
set DEBUG=* & npm run start
Automatically
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22{
"name" : "chatter" ,
"version" : "1.0.0" ,
"description" : "" ,
"main" : "index.js" ,
"scripts" : {
"start" : "nodemon ./index.js --exec babel-node -e js" ,
"test" : "DEBUG=* nodemon ./index.js --exec babel-node -e js"
},
"author" : "Emmanuel Henri" ,
"license" : "ISC" ,
"dependencies" : {
"express" : "^4.16.2" ,
"nodemon" : "^1.12.1" ,
"socket.io" : "^2.0.3"
},
"devDependencies" : {
"babel-cli" : "^6.26.0" ,
"babel-preset-env" : "^1.6.0" ,
"babel-preset-stage-0" : "^6.24.1"
}
}