Skip to content

Commit f3f0910

Browse files
committed
chapter 02 done
1 parent eeaaf48 commit f3f0910

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

how-to-build-chat-app-with-socket.io-and-angular/02-让用户不再匿名.md

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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
```
545545
exports.online = function(_userId, callback) {
@@ -564,42 +564,42 @@ exports.offline = function(_userId, callback) {
564564

565565
既然用户是否在线的状态已经存在数据库中了,那接下来将其读出来显示在聊天室的右侧就行啦!
566566

567-
首先修改room controller,不但从服务端读取messages,同时还要读取在线的用户列表
567+
首先修改房间列表的控制器RoomCtrl,从服务端读取的数据不但包括消息还有在线用户列表
568568

569569
```
570570
angular.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
```
585585
io.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
```
605605
exports.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
```
651651
io.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
```
697697
var mongoose = require('mongoose')
@@ -713,16 +713,16 @@ var Message = new Schema({
713713
module.exports = Message
714714
```
715715

716-
在消息中,我们存放了消息的内容和创建时间,甚至还将消息创建人的详细信息也包含在了消息里,这样做的好处是,浪费一点空间,缩短查询时的时间;其次,消息中的creator数据并不需要保持绝对的正确
716+
在消息中,我们存放了消息的内容和创建时间,还将消息创建人的详细信息也包含在了消息里,这样做的好处是,浪费一点空间,缩短查询时的时间;因为消息中的creator数据并不需要保持绝对的一致性
717717

718-
根据Scheme生成Message模型类
718+
在models/index.js中,根据Schema生成Message模型
719719

720720
```
721721
// ...
722722
exports.Message = mongoose.model('Message', require('./message'))
723723
```
724724

725-
添加一个消息的controller,实现消息的写入和查询:
725+
在服务端添加一个消息的控制器'controllers/message.js',实现消息的写入和查询:
726726

727727
```
728728
var 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
```
805806
angular.module('techNodeApp', ['ngRoute', 'angularMoment']).
806807
run(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
```
820822
io.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

Comments
 (0)