使用Node.js+Socket.IO实现在线聊天实
通常采用实时通讯方案,常见的是:
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接。
长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。
Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
WebSocket协议,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在此WebSocket协议中,为我们实现即时服务带来了两大好处:
1. Header
互相沟通的Header是很小的-大概只有 2 Bytes
2. Server Push
服务器的推送,服务器不再被动的接收到浏览器的request之后才返回数据,而是在有新数据时就主动推送给浏览器。
安装Node.js
根据自己的操作系统,去Node.js官网下载安装即可。如果成功安装。在命令行输入node -v和npm -v应该能看到相应的版本号。
node -v v5.5.0 npm -v 3.5.3
搭建WebSocket服务端
进入到你的工作目录,如/work/www/server,新建一个名为 package.json的文件,内容如下:
{ "name": "realtime-server", "version": "0.0.1", "description": "my first realtime server", "dependencies": { "express": "^4.13.4", "socket.io": "^1.4.6" } }
接下来使用npm命令安装express和socket.io
npm install --save express
npm install --save socket.io
接下来可以开始编写服务端的代码了,新建一个文件:index.js
var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); app.get('/', function(req, res){ res.send('<h1>Welcome Realtime Server</h1>'); }); //在线用户 var onlineUsers = {}; //当前在线人数 var onlineCount = 0; io.on('connection', function(socket){ console.log('a user connected'); //监听新用户加入 socket.on('login', function(obj){ //将新加入用户的唯一标识当作socket的名称,后面退出的时候会用到 socket.name = obj.userid; //检查在线列表,如果不在里面就加入 if(!onlineUsers.hasOwnProperty(obj.userid)) { onlineUsers[obj.userid] = obj.username; //在线人数+1 onlineCount++; } //向所有客户端广播用户加入 io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj}); console.log(obj.username+'加入了聊天室'); }); //监听用户退出 socket.on('disconnect', function(){ //将退出的用户从在线列表中删除 if(onlineUsers.hasOwnProperty(socket.name)) { //退出用户的信息 var obj = {userid:socket.name, username:onlineUsers[socket.name]}; //删除 delete onlineUsers[socket.name]; //在线人数-1 onlineCount--; //向所有客户端广播用户退出 io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj}); console.log(obj.username+'退出了聊天室'); } }); //监听用户发布聊天内容 socket.on('message', function(obj){ //向所有客户端广播发布的消息 io.emit('message', obj); console.log(obj.username+'说:'+obj.content); }); }); http.listen(3000, function(){ console.log('listening on *:3000'); });
命令行运行node index.js,如果一切顺利,你应该会看到返回的listening on *:3000字样,这说明服务已经成功搭建了。此时浏览器中打开http://127.0.0.1:3000应该可以看到正常的欢迎页面。
客户端代码实现
进入客户端工作目录/work/www/client,新建一个index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="format-detection" content="telephone=no"/> <meta name="format-detection" content="email=no"/> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" name="viewport"> <title>多人聊天室</title> <link rel="stylesheet" type="text/css" href="./style.css" /> <!--[if lt IE 8]><script src="./json3.min.js"></script><![endif]--> <script src="http://127.0.0.1:3000/socket.io/socket.io.js"></script> </head> <body> <div id="loginbox"> <div style="width:260px;margin:200px auto;"> 请先输入你在聊天室的昵称 <br/> <br/> <input type="text" style="width:180px;" placeholder="请输入用户名" id="username" name="username" /> <input type="button" style="width:50px;" value="提交" onclick="CHAT.usernameSubmit();"/> </div> </div> <div id="chatbox" style="display:none;"> <div style="background:#3d3d3d;height: 28px; width: 100%;font-size:12px;"> <div style="line-height: 28px;color:#fff;"> <span style="text-align:left;margin-left:10px;">Websocket多人聊天室</span> <span style="float:right; margin-right:10px;"><span id="showusername"></span> | <a href="javascript:;" onclick="CHAT.logout()" style="color:#fff;">退出</a></span> </div> </div> <div id="doc"> <div id="chat"> <div id="message" class="message"> <div id="onlinecount" style="background:#EFEFF4; font-size:12px; margin-top:10px; margin-left:10px; color:#666;"> </div> </div> <div class="input-box"> <div class="input"> <input type="text" maxlength="140" placeholder="请输入聊天内容,按Ctrl提交" id="content" name="content"> </div> <div class="action"> <button type="button" id="mjr_send" onclick="CHAT.submit();">提交</button> </div> </div> </div> </div> </div> <script type="text/javascript" src="./client.js"></script> </body> </html>
我们主要看看里面的4个文件请求:
1、127.0.0.1:3000/socket.io/socket.io.js
2、style.css
3、json3.min.js
4、client.js
第1个JS是Socket.IO提供的客户端JS文件,在前面安装服务端的步骤中,当npm安装完socket.io并搭建起WebServer后,这个JS文件就可以正常访问了。
第2个style.css文件没什么好说的,就是样式文件而已。
第3个JS只在IE8以下版本的IE浏览器中加载,目的是让这些低版本的IE浏览器也能处理json,这是一个开源的JS,详见:http://bestiejs.github.io/json3/
第4个client.js是完整的客户端的业务逻辑实现代码。
上面所有的客户端和服务端的代码可以从Github上获得,点这里跳转到Github项目主页,或者在命令行将代码Clone到本地。
git clone https://github.com/plhwin/nodejs-socketio-chat.git
下载本地后有两个文件夹 client 和 server,client文件夹是客户端源码,可以放在Nginx/Apache的WebServer中。
进入客户端工作目录/work/www/client,修改client.js文件第100行,将链接指向本地服务器
//连接websocket后端服务器 this.socket = io.connect('ws://127.0.0.1:3000');
以上所以工作完成。
浙公网安备 33010602011771号