项目介绍
基于websocket的一个简单的聊天室
技术栈 express+socket.io+animate.css+angular
关于websocket不了解的点我,而socket.io是对websocket进行封装,提供通用接口。
Github项目地址
安装与使用
| 1 2 3 4 5 6 7
 | git clone https://github.com/ShanaMaid/websocket-express-webchat.git  #下载项目 npm install  #安装依赖 node app.js  #启动服务 访问  http://localhost/  #进入聊天室
 | 
功能
- 进入房间通知
- 离开房间通知
- 消息接收与发送
- 在线列表
- 服务器端信息备份
动态GIF
 
实现
思路
利用on绑定事件,emit触发绑定事件,服务器端与客户端进行交互
| 1 2
 | socket.on(eventName,callBack)  #绑定事件,eventName可以自定义 socket.emit(eventName,data) #触发事件,发送data
 | 
更多关于socket.io的详细信息请移步官方文档,点我。
服务端
首先添加我们需要使用的模块
| 1 2 3
 | var express = require('express'); var socket = require('socket.io'); var fs = require('fs');
 | 
然后从配置文件config.json读取一些我们需要的关于聊天室的一些配置信息,关于配置文件
| 1 2 3 4
 | var history_num = config.history_num ; //服务器缓存的历史消息条数 var port = config.sever_port;	//端口号 var backup = config.backup; //是否开启备份 var backup_filename = config.backup_filename; //备份文件名字
 | 
定义person与history两个数组,用于存储在线人员的名称与服务端缓存的消息条数(即用户第一次进入聊天室推送的历史消息条数)
| 1 2
 | var person = [];//记录在线情况 var history = [];//需要缓存的消息
 | 
监听port端口号,创建一个socket对象io
| 1 2 3
 | var app = express(); var server = app.listen(port); var io = new socket(server);
 | 
编写connection事件,响应客户端的连接请求,返回客户端socket,编写客户端要emit的事件
…………………………表示代码省略部分,完整代码点击Github项目地址
| 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
 | io.on('connection',  (socket) => { 	…………………………   	socket.emit('history',history); #发送服务器记录的历史消息 	io.sockets.emit('updatePerson', person); #进行广播,触发所有客户端的updatePerson事件,更新在线列表人员 	…………………………  	socket.on('sendMsg', (data) => { #发送消息事件 		………………………… 		io.sockets.emit('news',obj); #进行广播,触发所有客户端的news事件,更新信息。 	}); 	socket.on('setUserName',(data) => { #设定用户名事件 		………………………… 		io.sockets.emit('updatePerson',person); #进行广播,触发所有客户端的updatePerson事件,更新在线列表人员 		io.sockets.emit('news',{content:user+'进入房间',time:Now(),name:'系统消息'}); #进行广播,触发所有客户端的news事件,通知进入房间 		………………………… 	}); 	socket.on('disconnect',  (socket) => { #掉线事件 		if(user!='') { 			person.forEach((value,index)=>{ 				if (value===user) { 					person.splice(index,1); 				} 			}); 		io.sockets.emit('news', {content: user + '离开房间', time: Now(), name: '系统消息'}); 		io.sockets.emit('updatePerson', person); 		} 	}); });
 | 
客户端
变量初始化
| 1 2 3 4 5 6
 | $scope.data = []; 	#接收-消息队列 $scope.name = '';       #用户名 $scope.content = '';    #发送信息内容 $scope.personnum = 0;   #在线人数 $scope.personlist = []; #在线人员列表 $scope.flag = false;    #是否取名
 | 
创建客户端socket
| 1 2
 | const socket_url = 'http://localhost'; var socket = io(socket_url);
 | 
完成服务器端的emit的事件
| 1 2 3 4 5 6 7 8 9 10 11
 | socket.on('news', (data) => {    …………………… }); socket.on('history', (data) => {     …………………… }); socket.on('updatePerson', (data) => {     …………………… });
 | 
config.json配置文件
| 1 2 3 4 5 6
 | {   "history_num":20,  #服务器缓存的历史信息条数   "sever_port":80,	#服务器监听端口号   "backup":true,    #是否开启服务端信息备份   "backup_filename":"./backup/example.json"  #备份文件名字 }
 | 
聊天信息备份
聊天信息以json格式存储在example.json文件中!
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 | function backupMsg(filename,obj) { 	var backup_file = fs.readFileSync(backup_filename); 	var msg= backup_file!='' ? JSON.parse(backup_file) : []; 	msg.push(obj); 	var str = '[\n' 	msg.forEach((value,index) =>{ 		if (index!==0){ 			str+=',\n'; 		} 		str += '  {\n    "name":"'+value.name+'",\n    "time":"'+value.time+'",\n    "content":"'+value.content+'"\n  }' 	} ); 	str += '\n]'; 	fs.writeFile(filename, str, (err) => { 		if(err) 			console.log("fail write :" + arr +  "   "+Date() + "\n error:"+err); 	}); }
 | 
备份信息示例
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 | [   {     "name":"测试人员1",     "time":"2017-2-13  23:32:17",     "content":"一条简单的测试信息"   },   {     "name":"测试人2",     "time":"2017-2-13  23:33:42",     "content":"那你很棒哦"   },   {     "name":"测试人3",     "time":"2017-2-13  23:33:54",     "content":"肯定很棒哦"   } ]
 | 
总结
websocket实现了浏览器与服务器全双工通信。
举个栗子,原来是这样的
轮询机制:
| 1 2 3 4 5 6 7 8 9
 | 客户端:服务器,你有没有消息要给我啊? 服务器:有。 客户端:服务器,你有没有消息要给我啊? 服务器:没有。 ——————————无限重复———————————— 客户端:服务器,你有没有消息要给我啊? 服务器:没有。 客户端:服务器,你有没有消息要给我啊? 服务器:你烦不烦啊~
 | 
而现在的websocket:
| 1 2 3 4 5
 | 客户端:服务器,你有我的消息了记得call我。 服务器:OK! ——————————当有消息的时候———————— 服务器:有你的消息了,客户端。 客户端:收到。
 | 
##后记
- 聊天室在线人员显示错误,多人离线时会出现在线列表混乱。目前已修复
- 聊天室历史加载记录,存在错误,已修复!
Github项目地址,欢迎各位交流学习!