项目介绍
基于websocket的一个简单的聊天室
技术栈 express+socket.io+animate.css+angular
关于websocket不了解的点我,而socket.io是对websocket进行封装,提供通用接口。
Github项目地址
安装与使用
git clone https://github.com/ShanaMaid/websocket-express-webchat.git #下载项目
npm install #安装依赖
node app.js #启动服务
访问 http://localhost/ #进入聊天室
功能
- 进入房间通知
- 离开房间通知
- 消息接收与发送
- 在线列表
- 服务器端信息备份
动态GIF
聊天室
在线聊天室Demo
手机与电脑均可访问,点我进入在线版
实现
思路
利用on绑定事件,emit触发绑定事件,服务器端与客户端进行交互
socket.on(eventName,callBack) #绑定事件,eventName可以自定义
socket.emit(eventName,data) #触发事件,发送data
更多关于socket.io的详细信息请移步官方文档,点我。
服务端
首先添加我们需要使用的模块
var express = require('express');
var socket = require('socket.io');
var fs = require('fs');
然后从配置文件config.json读取一些我们需要的关于聊天室的一些配置信息,关于配置文件
var history_num = config.history_num ; //服务器缓存的历史消息条数
var port = config.sever_port; //端口号
var backup = config.backup; //是否开启备份
var backup_filename = config.backup_filename; //备份文件名字
定义person与history两个数组,用于存储在线人员的名称与服务端缓存的消息条数(即用户第一次进入聊天室推送的历史消息条数)
var person = [];//记录在线情况
var history = [];//需要缓存的消息
监听port端口号,创建一个socket对象io
var app = express();
var server = app.listen(port);
var io = new socket(server);
编写connection事件,响应客户端的连接请求,返回客户端socket,编写客户端要emit的事件…………………………表示代码省略部分,完整代码点击Github项目地址
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!='') {
io.sockets.emit('news', {content: user + '离开房间', time: Now(), name: '系统消息'}); #进行广播,离开房间
person.splice(id,1);
}
io.sockets.emit('updatePerson', person);
});
});
客户端
变量初始化
$scope.data = []; #接收-消息队列
$scope.name = ''; #用户名
$scope.content = ''; #发送信息内容
$scope.personnum = 0; #在线人数
$scope.personlist = []; #在线人员列表
$scope.flag = false; #是否取名
创建客户端socket
const socket_url = 'http://localhost';
var socket = io(socket_url);
完成服务器端的emit的事件
socket.on('news', (data) => {
……………………
});
socket.on('history', (data) => {
……………………
});
socket.on('updatePerson', (data) => {
……………………
});
config.json配置文件
{
"history_num":20, #服务器缓存的历史信息条数
"sever_port":80, #服务器监听端口号
"backup":true, #是否开启服务端信息备份
"backup_filename":"./backup/example.json" #备份文件名字
}
聊天信息备份
聊天信息以json格式存储在example.json文件中!
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);
});
}
备份信息示例
[
{
"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实现了浏览器与服务器全双工通信。
举个栗子,原来是这样的
轮询机制:
客户端:服务器,你有没有消息要给我啊?
服务器:有。
客户端:服务器,你有没有消息要给我啊?
服务器:没有。
——————————无限重复————————————
客户端:服务器,你有没有消息要给我啊?
服务器:没有。
客户端:服务器,你有没有消息要给我啊?
服务器:你烦不烦啊~
而现在的websocket:
客户端:服务器,你有我的消息了记得call我。
服务器:OK!
——————————当有消息的时候————————
服务器:有你的消息了,客户端。
客户端:收到。
Github项目地址,欢迎各位交流学习!
坚持原创技术分享,您的支持将鼓励我继续创作! 赏
支付宝打赏