Today I will implement a simple chat room, using nodejs in the background, and socket.io in the client and server communication. This is a relatively mature websocket framework.
Initial work
1. Install express, use this to host socket.io and static pages. The command npm install express --save, --save can add the package to the package.json file.
2. Install socket.io, and command npm install socket.io --save.
Writing server code
First we host the website through express and attach it to the socket.io instance, because the first connection of socket.io requires the http protocol
The code copy is as follows:
var express = require('express'),
io = require('socket.io');
var app = express();
app.use(express.static(__dirname));
var server = app.listen(8888);
var ws = io.listen(server);
Add a server connection event. When the client connection is successful, an announcement is issued to tell all online users, and when the user sends a message, a broadcast is sent to notify other users.
The code copy is as follows:
ws.on('connection', function(client){
console.log('/033[96msomeone is connect/033[39m /n');
client.on('join', function(msg){
// Check for duplication
if(checkNickname(msg)){
client.emit('nickname', 'There is a duplicate nickname!');
}else{
client.nickname = msg;
ws.sockets.emit('announcement', 'system', msg + ' Joined the chat room!');
}
});
// Listen to send messages
client.on('send.message', function(msg){
client.broadcast.emit('send.message',client.nickname, msg);
});
// Notify other users when disconnecting
client.on('disconnect', function(){
if(client.nickname){
client.broadcast.emit('send.message','system', client.nickname + 'Leave the chat room!');
}
})
})
Since the client is identified by a nickname, the server needs a function to detect duplication of nicknames
The code copy is as follows:
// Check if the nickname is duplicated
var checkNickname = function(name){
for(var k in ws.sockets.sockets){
if(ws.sockets.sockets.hasOwnProperty(k)){
if(ws.sockets.sockets[k] && ws.sockets.sockets[k].nickname == name){
return true;
}
}
}
return false;
}
Write customer service code
Since the server uses a third-party websokcet framework, the front-end page needs to refer to the socket.io client code separately. The source file can be found from the socket.io module. The path under Windows is node_modules/socket.io/node_modules/socket.io-client/dist. There are development versions and compressed versions here, and the default references to the development version are enough.
The front-end mainly processes input nickname checks, message processing, and the complete code is as follows:
The code copy is as follows:
<!DOCTYPE html>
<html>
<head>
<title>socket.io chat room example</title>
<meta charset="utf-8">
<link rel="stylesheet" href="css/reset.css"/>
<link rel="stylesheet" href="css/bootstrap.css"/>
<link rel="stylesheet" href="css/app.css"/>
</head>
<body>
<div>
<div id="chat">
<ul id="chat_conatener">
</ul>
</div>
<div>
<textarea ></textarea>
<button id="clear">Clear screen</button>
<button id="send">Send</button>
</div>
</div>
<script type="text/javascript" src="js/socket.io.js"></script>
<script type="text/javascript">
var ws = io.connect('http://172.16.2.184:8888');
var sendMsg = function(msg){
ws.emit('send.message', msg);
}
var addMessage = function(from, msg){
var li = document.createElement('li');
li.innerHTML = '<span>' + from + '</span>' + ' : ' + msg;
document.querySelector('#chat_conatener').appendChild(li);
// Set the scroll bar in the content area to the bottom
document.querySelector('#chat').scrollTop = document.querySelector('#chat').scrollHeight;
// and set focus
document.querySelector('textarea').focus();
}
var send = function(){
var ele_msg = document.querySelector('textarea');
var msg = ele_msg.value.replace('/r/n', '').trim();
console.log(msg);
if(!msg) return;
sendMsg(msg);
// Add message to your own content area
addMessage('you', msg);
ele_msg.value = '';
}
ws.on('connect', function(){
var nickname = window.prompt('Enter your nickname!');
while(!nickname){
nickname = window.prompt('Nickname cannot be empty, please re-enter!')
}
ws.emit('join', nickname);
});
// There are duplicate nicknames
ws.on('nickname', function(){
var nickname = window.prompt('The nickname has duplicates, please re-enter!');
while(!nickname){
nickname = window.prompt('Nickname cannot be empty, please re-enter!')
}
ws.emit('join', nickname);
});
ws.on('send.message', function(from, msg){
addMessage(from, msg);
});
ws.on('announcement', function(from, msg){
addMessage(from, msg);
});
document.querySelector('textarea').addEventListener('keypress', function(event){
if(event.which == 13){
send();
}
});
document.querySelector('textarea').addEventListener('keydown', function(event){
if(event.which == 13){
send();
}
});
document.querySelector('#send').addEventListener('click', function(){
send();
});
document.querySelector('#clear').addEventListener('click', function(){
document.querySelector('#chat_conatener').innerHTML = '';
});
</script>
</body>
</html>
The complete code compression file is provided here
Summarize
Nodejs is a good thing, especially when it comes to handling messaging and network programming, natural asynchronous IO.