不得不说,上手AngularJS比我想象得难多了,把官网提供的PhoneCat例子看完,又跑到慕课网把大漠穷秋的AngularJS实战系列看了一遍,对于基本的使用依然有很多说不清道不明的疑惑,于是决定通过做一个在线聊天室帮助理解。DEMO可以戳→chat room,代码可以戳→ChatRoom-AngularJS。
清晰图可以戳 //img.jbzj.com/file_images/article/201508/201508281040051.gif
功能
着手开发之前,首先明确一下需要实现的功能:
新用户登入,广播通知其他用户
用户下线,广播通知其他用户
可显示在线人数及列表
可群聊,可私信
用户若发送群消息,广播通知其他所有用户
用户若发送私信,单独通知收方界面
因为自己是个审美渣,所以全靠bootstrap了,另外还模仿了下微信聊天记录里的气泡设计。
界面分左右两个板块,分别用于显示在线列表和聊天内容。
在左侧的在线列表中,点击不同项可以切换右侧板块的聊天对象。
右侧显示与当前聊天对象的对话记录,不过仅显示最近的30条。每一条聊天记录内容包括发送人的昵称及头像、发送时间、消息内容。关于头像,这里做简单处理,用填充了随机色的方块代替。另外,自己发出去的消息与收到的消息样式自然要做不同设计,所有效果可以看下图。
清晰图可以戳 //img.jbzj.com/file_images/article/201508/201508281040052.png
服务端
服务端我们用Node.js以及混入express、socket.io来开发,在程序根目录打开终端,执行:
复制代码 代码如下:
npm init
根据提示,生成一个package.json文件。打开并配置依赖项:
"dependencies": { "express": "^4.13.3", "socket.io": "^1.3.6" }
之后执行 npm install 安装依赖模块。
接下来,我们在根目录下新建app.js,在其中写Server端代码。再新建public文件夹,存放client端代码。
app.js中主要内容如下:
var express = require('express'); var app = require('express')(); var http = require('http').createServer(app); var io = require('socket.io')(http); app.use(express.static(__dirname + '/public')); app.get('https://www.jb51.net/', function (req, res) { res.sendfile('index.html'); }); io.on('connection',function(socket){ socket.on('addUser',function(data){ //有新用户进入聊天室 }); socket.on('addMessage',function(data){ //有用户发送新消息 }); socket.on('disconnect', function () { //有用户退出聊天室 ); }); http.listen(3002, function () { console.log('listening on *:3002'); });
在上面的代码中,我们为以下事件添加了监听:
-addUser,有新用户进入聊天室
该事件由客户端输入昵称后触发,服务端收到后对昵称是否已存在进行判断,如果已存在,通知客户端昵称无效:
复制代码 代码如下:
socket.emit('userAddingResult',{result:false});
反之,通知客户端昵称有效以及当前所有已连接的用户信息,并把新用户信息广播给其他已连接用户:
socket.emit('userAddingResult',{result:true}); allUsers.push(data);//allUsers保存了所有用户 socket.emit('allUser',allUsers);//将所有在线用户发给新用户 socket.broadcast.emit('userAdded',data);//广播欢迎新用户,除新用户外都可看到
其中需要注意'socket.emit'与'socket.broadcast.emit'的区别,可以查看这篇博文socket.io emit的几种用法解释:
// send to current request socket client socket.emit('message', "this is a test"); // sending to all clients except sender socket.broadcast.emit('message', "this is a test");
-addMessage,有用户发送新消息
在此事件监听里,需要分成两类情况处理:
1.私信
如果消息是发给特定用户A,那么就需要获取A对应的socket实例,然后调用其emit方法。所以每当一个客户端连接到Server端时,我们得把其socket实例保存起来,以备后续之需。
复制代码 代码如下:
connectedSockets[nickname]=socket;//以昵称作下标,保存每个socket实例,发私信需要用
需要发私信时,取出socket实例做操作即可:
复制代码 代码如下:
connectedSockets[nickname].emit('messageAdded',data)
2.群发
群发就比较简单了,用broadcast方法即可:
复制代码 代码如下:
socket.broadcast.emit('messageAdded',data);//广播消息,除原发送者外都可看到
-disconnect,有用户退出聊天室
需要做三件事情:
1.通知其他用户“某用户下线”
复制代码 代码如下:
socket.broadcast.emit('userRemoved', data);
2.将用户从保存了所有用户的数组中移除
3.将其socket实例从保存了所有客户端socket实例的数组中移除
复制代码 代码如下:
delete connectedSockets[nickname]; //删除对应的socket实例
运行一下服务端代码,观察有无错误:
复制代码 代码如下:
node app.js
若没什么问题,继续编写客户端的代码。
客户端
在public目录下新建'index.html',客户端需要用到bootstrap、angularjs、socket.io、jQuery以及我们自己的js和css文件,先把这些文件用标签引入。