Popush源代码学习报告
@肖剑楠 2011013223
序
Popush采用NodeJS架构,网络通信使用了Socket.IO,同时基于Backbone.js实现了MVC架构。与Mongodb进行数据交互的部分封装成为Model,位于/models文件夹下;定义表层交互方式的部分封装为View,位于/static/js/views文件夹下,另外/static/js/room下的代码实现了代码编辑、实时聊天(尚不完整)等功能,/static/js/router.js定义了服务器的路由,根目录下的app.js完成了服务器的启动以及事件监听的处理。
C/S架构交互方式
前面提到Popush的网络通信基于Socket.IO。在app.js使用node启动时,服务器开始监听socket连接,当连接之后,会自动处理客户端发送的version,register,relogin
等请求,对相应请求的处理如以下方式定义
socket.on('request_name', function(data) {/* do something */});
当客户端发出请求时,依照如下方式
app.socket.emit('request_name', {para1: value1, ...});
View模块
在/static/index.html(561-572)中,引用了一系列*-view.js文件
<script type="text/javascript" src="js/views/login-view.js"></script>
<script type="text/javascript" src="js/views/register-view.js"></script>
......
在这些文件中,都有相似的一句代码
app.views['register'] = new app.RegisterView();
OR app.views['account'] = new app.AccountView();
这句代码的作用在于将所有的页面初始化,并存储在全局变量app
的views
属性中,方便之后的及时调用。 app.*View
的定义由以下几个部分构成events, initialize,...
,其中events
定义了该页面上的响应事件,initialize
定义了页面的初始化逻辑,另外还有一些其他的方法,主要用于定义事件的处理逻辑。
Model模块
与Mongodb的数据直接交互定义在/models/*DAO.js文件中,共有两个文件docDAO.js和userDAO.js,分别实现了用户信息和文档内容的增、删、查、更新等功能的支持。 与数据库相关的所有操作由变量db
完成,db
通过require
数据库的配置来得到类似于connection的变量,通过调用该变量的insert,findOne,find,update
等方法,即可实现与数据库的交互。由于Mongodb为对象型数据库,只需将查找条件以JSON格式作为参数传递进去即可,不需要编写复杂的SQL语句。
业务实现逻辑举例分析
以文件分享为例:
-
客户端请求 file-view.js(13),在
events
中定义了a.file-go-share
的点击事件处理函数为share
,app.views.shares.shareModel = this.model; // 获取对model的引用 app.collections['shares'].set(this.model.get('members')); // 获取该文件的成员列表 $('#share').modal('show'); // 显示share对话框
-
值得一提的是,SharerlistView对应的是
app.collections['share']
,同时SharerlistView中的el
属性定义了在html中绑定的元素位置#share
,即为file-view.js中函数share所调用的#share
,可以理解的是,*-view.js文件通过定义一系列的绑定事件,并在此之前已经在html中动态生成了对应的标签及id
等属性,其他函数只需通过jQuery的selector访问即可。 -
在share对话框中,用户选择一个用户之后,点击分享按钮,触发share函数,该绑定在sharerlist-view.js(9)中定义,然后获取参数,校验之后,调用
app.socket.emit('share', {/* params */})
将请求发送给服务器。 -
服务器监听
share
请求,在app.js(346)中定义,如果会话失效,则返回'unauthorized',否则,调用docDAO
的addMember
函数将该记录添加到数据库中,并返回'share'
响应,如果未出现异常,则将该信息广播至所有正在访问该文件的其他用户。客户端在收到'share'
响应后,会调用detach函数执行相关处理。