Meteor-DDP
DDP
关于什么是DDP,我花了好长时间翻译了DDP Specification,这篇翻译的领域词汇倒不多,关键字倒是挺多的,所以翻译起来特别绕口。
初始化应用
通过Meteor快速构建一个项目app,然后在会生成如下文件目录:
> meteor create app
> cd app
> meteor remove autopublish
> meteor
---------------------------
目录结构:
app
├── .meteor
├── app.css
├── app.html
└── app.js
修改如下文件:
file: /app/app.html
<head>
<title>app</title>
</head>
<body>
posts
{{> posts}}
</body>
<template name="posts">
<ul>
{{#each posts}}
<li>{{message}}</li>
{{/each}}
</ul>
</template>
file: /app/app.js
//定义集合,服务端、客户端共享
Posts = new Meteor.Collecction('posts');
//客户端代码
if(Meteor.isClient){
//构建模板助理
Template.posts.helpers({
posts:function(){
return Posts.find();
}
});
//订阅posts
Meteor.subscribe('posts',[],function(){
console.log('[client] -- posts订阅完毕');
});
}
//服务端代码
if(Meteor.isServer){
//初始化
Meteor.startup(function(){
Posts.remove({});
for(var i = 1 ; i <= 3; i++){
Posts.insert({
message:'消息' + i
});
}
});
//发布posts
Meteor.publish('posts',function(){
return Posts.find();
});
}
以上代码非常熟悉,出于Meteor基本掌握内容。
Node-DDP
现在我们来使用Nodejs构建DDP,在命令行中,我们在app同级目录下构建文件夹node-client,进去后通过npm安装需要的模块:
> npm install -d ddp
创建文件client.js,编写如下代码:
file: /node-client/client.js
//引入DDP模块
var DDPClient = require('ddp');
//创建客户端连接器
var client = new DDPClient({
host:'localhost',
port:3000
});
//监听消息
client.on('message',function(data,flags){
console.log('[DDP消息]: ',data);
});
//连接
client.connect(function(){
//客户端订阅posts
client.subscribe('posts',[],function(){
console.log('[posts订阅完毕]');
});
});
用NodeJS运行这段代码,剩下的事情就不用管了:
> node /node-client/client.js
接着我们修改app.js,取消服务端的发布
file: /app/app.js
if (Meteor.isClient) {
//注意,我们只将Posts集合提供给客户端,服务端是无法使用的
var Posts = new Meteor.Collection('posts');
Template.posts.helpers({
posts:function(){
return Posts.find();
}
});
Meteor.subscribe('posts',[],function(){
console.log('posts已订阅');
});
}
if (Meteor.isServer) {
//服务器发布posts,
Meteor.publish('posts',function(){
var me = this;
for(var i = 1; i <= 3; i++){
me.added('posts',Meteor.uuid(),{
message:'消息' + i
});
}
me.ready();
});
}
我们运行Meteor项目,然后就在浏览器上看到效果了!
Node-DDP附录
关于Node-DDP可以参阅Subscriptions and DDP 视频来进行搭建和扩展。但这里要说明关于本视频的一些问题。
这个视频针对的Meteor版本应该是0.5.x
的版本,对于0.6.x
的版本是不适用的。例如set
、unset
、complete
、flush
等方法在0.6.x
版本中是无法使用的,参阅Meteoer的文档中心-Publish and subscribe可以比对出以上方法进行了修订。set
方法设置为added
方法,unset
设置为removed
方法,complete
和flush
应该被合并为ready
方法。Meteor.uuid()
经过测试是可以继续沿用的,而Meteor.userId()
不是Meteor.uuid()
的替换,他是在启用账户包之后存放当前登录用户的。另外Meteor.publish
中使用me.userId()
也不是Meteor.uuid()
的替换。
关于Meteor.uuid()
官方并没有介绍,有人提出过,详见GitHub-Meteor-Issues。官方出于安全考虑是想避免在前端使用字符串的_id
,而采用这样自动获取的方式。从一些回复中我们可以看到这个方法返回一个JSON对象,由系统自动获取。不过官方考虑今后会增加这个api
,只是时间的问题而已(PS:过去8个月这个api还是没增加)。
Meteor-DDP
之前是使用nodejs作为DDP,需要同时开启两个命令窗口分别跑NodeJS和Meteor。现在,有提供在浏览器端运行的DDP,可以附加在Meteor的客户端上。
首先,点击下载Meteor-DDP。
接着我们可以通过两种方式使用Meteor-DDP:
第一种方式是将meteor-ddp.js放置在Meteor的public目录下,然后app.html中导入js文件即可:
file: /app/app.html
<script type="text/javascript" src="/meteor-ddp.js"></script>
第二种方式是将Meteor-DDP打成Meteor的包(Package),具体方式查看Meteor的教程。这种方式需要将源码用闭包封装,并加上关键代码:
(function(window){
//meteor-ddp.js源码全部复制到这
//以下是最后需要添加的关键代码:
window.MeteorDdp = MeteorDdp;
})(window);
我是采用第二种方式,然后我们在Meteor中添加Meteor-DDP的Package。需要注意的是,Meteor-DDP是依赖JQuery(1.5+)的。
我们可以按照之前初始化项目的过程再做一个新项目。然后修改app.js
file: /app/app.js
if (Meteor.isClient) {
//使用Meteor-DDP
var ddp = new MeteorDdp('ws://127.0.0.1:3000/websocket');
ddp.connect().done(function(){
console.log('[DDP Connected]');
ddp.subscribe('posts',[]).fail(function(){
console.log('[client posts subscription failed]');
});
});
var Posts = new Meteor.Collection('posts');
Template.posts.helpers({
posts:function(){
return Posts.find();
}
});
Meteor.subscribe('posts',[],function(){
console.log('posts已订阅');
});
}
if (Meteor.isServer) {
Meteor.publish('posts',function(){
var me = this;
for(var i = 1; i <= 3; i++){
me.added('posts',Meteor.uuid(),{
message:'消息' + i
});
}
me.ready();
});
}