@@ -477,13 +477,13 @@ angular.module('techNodeApp').controller('MessageCreatorCtrl', function($scope,
477477})
478478```
479479
480- 我想通过socket发送的消息不再是一个字符串 ,而是一个携带消息内容,和消息发送者信息的json对象;
480+ 通过socket发送的消息不再是一个字符串 ,而是一个携带消息内容,和消息发送者信息的json对象;
481481
482482重启服务器,登录发条消息,终于,TechNode的用户不再是匿名的了!
483483
484484#### 显示在线用户
485485
486- 如果能够看到哪些用户同时在线就好了,让我们开始实现这个功能吧 !
486+ 如果能够看到哪些用户在聊天室里就好了,让我们实现这个功能吧 !
487487
488488我们将用户是否在线的状态存储在数据库中,因此需要扩展User Schema的字段:
489489
@@ -499,7 +499,7 @@ var User = new Schema({
499499在用户登录或者登出是修改用户的在线状态:
500500
501501```
502- app.post('/ajax /login', function(req, res) {
502+ app.post('/api /login', function(req, res) {
503503 email = req.body.email
504504 if (email) {
505505 Controllers.User.findByEmailOrCreate(email, function(err, user) {
@@ -525,7 +525,7 @@ app.post('/ajax/login', function(req, res) {
525525 }
526526})
527527
528- app.get('/ajax /logout', function(req, res) {
528+ app.get('/api /logout', function(req, res) {
529529 _userId = req.session._userId
530530 Controllers.User.offline(_userId, function (err, user) {
531531 if (err) {
@@ -539,7 +539,7 @@ app.get('/ajax/logout', function(req, res) {
539539 })
540540})
541541```
542- 修改了login和logout这两个接口,在用户登录或者退出时更新用户的状态,online和offline这两个方法就比较容易 :
542+ 修改了login和logout这两个接口,在用户登录或者退出时更新用户的状态,online和offline这两个方法就比较简单了,修改controllers/user.js,添加下面两个接口 :
543543
544544```
545545exports.online = function(_userId, callback) {
@@ -564,42 +564,42 @@ exports.offline = function(_userId, callback) {
564564
565565既然用户是否在线的状态已经存在数据库中了,那接下来将其读出来显示在聊天室的右侧就行啦!
566566
567- 首先修改room controller,不但从服务端读取messages,同时还要读取在线的用户列表 :
567+ 首先修改房间列表的控制器RoomCtrl,从服务端读取的数据不但包括消息还有在线用户列表 :
568568
569569```
570570angular.module('techNodeApp').controller('RoomCtrl', function($scope, socket) {
571- socket.on('technode.read ', function (technode ) {
572- $scope.technode = technode
571+ socket.on('roomData ', function (room ) {
572+ $scope.room = room
573573 })
574- socket.on('messages.add ', function (message) {
574+ socket.on('messageAdded ', function (message) {
575575 $scope.technode.messages.push(message)
576576 })
577- socket.emit('technode.read ')
577+ socket.emit('getRoom ')
578578})
579579```
580580
581- 我们把messages和users都放到technode这个对象中 ,修改socket服务端,将在线用户列表和messages一起读出来发送给客户端 :
581+ 我们把messages和users都放到room这个对象中 ,修改socket服务端,将在线用户列表和消息列表一道读出来发送给客户端 :
582582
583583
584584```
585585io.sockets.on('connection', function(socket) {
586- socket.on('technode.read ', function() {
586+ socket.on('getRoom ', function() {
587587 Controllers.User.getOnlineUsers(function (err, users) {
588588 if (err) {
589589 socket.emit('err', {msg: err})
590590 } else {
591- socket.emit('technode.read ', {users: users, messages: messages})
591+ socket.emit('roomData ', {users: users, messages: messages})
592592 }
593593 })
594594 })
595- socket.on('messages.create ', function(message) {
595+ socket.on('createMessage ', function(message) {
596596 messages.push(message)
597- io.sockets.emit('messages.add ', message)
597+ io.sockets.emit('messageAdded ', message)
598598 })
599599})
600600```
601601
602- getOnlineUsers非常简单 :
602+ 别忘了在controllers/user.js中添加getOnlineUsers接口 :
603603
604604```
605605exports.getOnlineUsers = function(callback) {
@@ -609,15 +609,15 @@ exports.getOnlineUsers = function(callback) {
609609}
610610```
611611
612- 接下来就是把在线用户列表在客户端render出来了,其实只需要修改room的模板即可 :
612+ 接下来就是把在线用户列表在客户端render出来了,其实只需要修改房间视图room.html即可 :
613613
614614```
615615<div class="col-md-9">
616616 <div class="panel panel-default room">
617617 <div class="panel-heading room-header">TechNode</div>
618618 <div class="panel-body room-content">
619619 <div class="list-group messages" auto-scroll-to-bottom>
620- <div class="list-group-item message" ng-repeat="message in technode .messages">
620+ <div class="list-group-item message" ng-repeat="message in room .messages">
621621 <img src="{{message.creator.avatarUrl}}" title="{{message.creator.name}}" class="img-rounded"/>{{message.creator.name}}: {{message.message}}
622622 </div>
623623 </div>
@@ -634,7 +634,7 @@ exports.getOnlineUsers = function(callback) {
634634 <div class="panel-heading user-list-header">在线用户</div>
635635 <div class="panel-body user-list-content">
636636 <div class="list-group users">
637- <div class="list-group-item user" ng-repeat="user in technode .users">
637+ <div class="list-group-item user" ng-repeat="user in room .users">
638638 <img src="{{user.avatarUrl}}" title="{{user.name}}" class="img-rounded"/>{{user.name}}
639639 </div>
640640 </div>
@@ -643,9 +643,9 @@ exports.getOnlineUsers = function(callback) {
643643</div>
644644```
645645
646- 并么有什么复杂的地方,就如消息列表一样渲染就行 。
646+ 没有特别的地方,如消息列表一样渲染即可 。
647647
648- TechNode是基于socket的,用户上下线的概念并不仅限于登录和登出,用户通过socket脸上就是上线 ,用户socket断开就是离线了。我们来看看如何实现基于socket的用户上下线。
648+ TechNode是基于socket的,用户上下线的概念并不仅限于登录和登出,用户通过socket连上就是上线 ,用户socket断开就是离线了。我们来看看如何实现基于socket的用户上下线。
649649
650650```
651651io.sockets.on('connection', function(socket) {
@@ -656,7 +656,7 @@ io.sockets.on('connection', function(socket) {
656656 mesg: err
657657 })
658658 } else {
659- socket.broadcast.emit('users.add ', user)
659+ socket.broadcast.emit('online ', user)
660660 }
661661 })
662662 socket.on('disconnect', function() {
@@ -666,32 +666,32 @@ io.sockets.on('connection', function(socket) {
666666 mesg: err
667667 })
668668 } else {
669- socket.broadcast.emit('users.remove ', user)
669+ socket.broadcast.emit('offline ', user)
670670 }
671671 })
672672 });
673673 // ...
674674})
675675```
676- 我们添加了socket连上和断开的处理,通知客户端有用户连上或者下线了。客户端只需监听这两个事件即可:
676+ 我们添加了socket连上和断开的处理,通知客户端有用户连上或者下线了。客户端只需监听这两个事件即可,在房间控制器RoomCtrl添加对这两个事件的处理 :
677677
678678```
679- socket.on('users.add ', function (user) {
680- $scope.technode .users.push(user)
679+ socket.on('online ', function (user) {
680+ $scope.room .users.push(user)
681681})
682- socket.on('users.remove ', function (user) {
682+ socket.on('offline ', function (user) {
683683 _userId = user._id
684- $scope.technode .users = $scope.technode .users.filter(function (user) {
684+ $scope.room .users = $scope.room .users.filter(function (user) {
685685 return user._id != _userId
686686 })
687687})
688688```
689689
690690至此,本章最核心的部分已经完成,现在你可以在聊天室的右侧查看在线的用户的了。
691691
692- #### 消息持久化、系统消息
692+ #### 消息持久化和系统消息
693693
694- 到目前为止,聊天室的消息并没有存放在数据库中,而且消息没有创建时间等等一些参数 ,现在我们就来处理这些问题;首先创建一个消息的Scheme :
694+ 到目前为止,聊天室的消息并没有存放在数据库中,而且消息没有创建时间等等 ,现在我们就来处理这些问题。首先创建一个消息的Schema,在models中添加message.js,添加如下代码 :
695695
696696```
697697var mongoose = require('mongoose')
@@ -713,16 +713,16 @@ var Message = new Schema({
713713module.exports = Message
714714```
715715
716- 在消息中,我们存放了消息的内容和创建时间,甚至还将消息创建人的详细信息也包含在了消息里 ,这样做的好处是,浪费一点空间,缩短查询时的时间;其次,消息中的creator数据并不需要保持绝对的正确 。
716+ 在消息中,我们存放了消息的内容和创建时间,还将消息创建人的详细信息也包含在了消息里 ,这样做的好处是,浪费一点空间,缩短查询时的时间;因为消息中的creator数据并不需要保持绝对的一致性 。
717717
718- 根据Scheme生成Message模型类 :
718+ 在models/index.js中,根据Schema生成Message模型 :
719719
720720```
721721// ...
722722exports.Message = mongoose.model('Message', require('./message'))
723723```
724724
725- 添加一个消息的controller ,实现消息的写入和查询:
725+ 在服务端添加一个消息的控制器'controllers/message.js' ,实现消息的写入和查询:
726726
727727```
728728var db = require('../models')
@@ -743,12 +743,13 @@ exports.read = function(callback) {
743743 }, callback)
744744}
745745```
746+
746747查询时,我们按照消息的创建的时间倒叙排列,而且取最新的20条;
747748
748749接下来,我们修改与客户端通信的API部分:
749750
750751```
751- socket.on('technode.read ', function() {
752+ socket.on('getRoom ', function() {
752753 async.parallel([
753754 function(done) {
754755 Controllers.User.getOnlineUsers(done)
@@ -763,58 +764,59 @@ socket.on('technode.read', function() {
763764 msg: err
764765 })
765766 } else {
766- socket.emit('technode.read ', {
767+ socket.emit('roomData ', {
767768 users: results[0],
768769 messages: results[1]
769770 })
770771 }
771772 });
772773})
773- socket.on('messages.create ', function(message) {
774+ socket.on('createMessage ', function(message) {
774775 Controllers.Message.create(function (err, message) {
775776 if (err) {
776777 socket.emit('err', {msg: err})
777778 } else {
778- io.sockets.emit('messages.add ', message)
779+ io.sockets.emit('messageAdded ', message)
779780 }
780781 })
781782})
782783```
783784
784- 在这里我们使用async来进行数据库并行的读取 ,别忘记了使用npm安装async包。
785+ 在这里我们使用async来并行地对数据库进行读取 ,别忘记了使用npm安装async包。
785786
786- 前端作少许修改 ,显示消息发出的时间:
787+ 简单修改客户端的房间视图 ,显示消息发出的时间:
787788
788789```
789790<div class="list-group-item message" ng-repeat="message in technode.messages">
790791 <img src="{{message.creator.avatarUrl}}" title="{{message.creator.name}}" class="img-rounded"/>{{message.creator.name}}: {{message.content}}<time am-time-ago="message.createAt"></time>
791792</div>
792793```
793794
794- 在这里我们使用了一个名为am-time-ago的directive,这个directive可以动态地更新time中的时间显示 ,开始可能是` 几秒前 ` ,随着实现的推移 ,能够智能地便成` 1分钟前 ` 等等;使用angular-moment提供的 ,请使用` bower install angular-moment --save ` 安装这个模块,并在index.html进行引用 :
795+ 在这里我们使用了一个名为am-time-ago的Angular指令,这个指令可以动态地更新time标记中的时间显示 ,开始可能是` 几秒前 ` ,随着时间的推移 ,能够智能地便成` 1分钟前 ` 、 ` 1小时前 ` 等等;这个指令是angular-moment这个模块提供的 ,请使用` bower install angular-moment --save ` 安装这个模块,并在将其加入到index.html中 :
795796
796797```
797798<script type="text/javascript" src="/components/moment/moment.js"></script>
798799<script type="text/javascript" src="/components/angular-moment/angular-moment.js"></script>
799800<script type="text/javascript" src="components/moment/lang/zh-cn.js"></script>
800801```
801802
802- 我们添加了一个语言包, 需要在technode.js对angular-moment和语言包进行配置 :
803+ 我们不但加入了angular-moment.js,还添加了一个中文语言包。 需要在technode.js中添加对angular-moment.js的依赖,并将语言设置为中文 :
803804
804805```
805806angular.module('techNodeApp', ['ngRoute', 'angularMoment']).
806807run(function ($window) {
807808 $window.moment.lang('zh-cn')
809+ // ...
808810})
809811```
810812
811- 至此,我们将message持久化了,而且保存了消息的创建时间,并在前端将时间显示出来 。
813+ 至此,我们将消息保存进了数据库,还保存了消息的创建时间,并在客户端将时间显示出来,我们将消息持久化的任务完成了 。
812814
813- #### 提供一些系统消息
815+ #### 系统消息
814816
815817我们为用户提供了一些系统的消息,比如其他用户登录退出的信息等等;这部分消息都是临时的,因此我们不会把它们加入到数据库中,动态生成即可。
816818
817- 比如我们添加两个用户登录和登出的消息 :
819+ 比如我们添加有用户登录和登出的消息 :
818820
819821```
820822io.sockets.on('connection', function(socket) {
@@ -825,8 +827,8 @@ io.sockets.on('connection', function(socket) {
825827 mesg: err
826828 })
827829 } else {
828- socket.broadcast.emit('users.add ', user)
829- socket.broadcast.emit('messages.add ', {
830+ socket.broadcast.emit('online ', user)
831+ socket.broadcast.emit('messageAdded ', {
830832 content: user.name + '进入了聊天室',
831833 creator: SYSTEM,
832834 createAt: new Date()
@@ -840,8 +842,8 @@ io.sockets.on('connection', function(socket) {
840842 mesg: err
841843 })
842844 } else {
843- socket.broadcast.emit('users.remove ', user)
844- socket.broadcast.emit('messages.add ', {
845+ socket.broadcast.emit('offline ', user)
846+ socket.broadcast.emit('messageAdded ', {
845847 content: user.name + '离开了聊天室',
846848 creator: SYSTEM,
847849 createAt: new Date()
0 commit comments