Meteor-DDP
发布于 11 年前 作者 a272121742 11740 次浏览 最后一次编辑是 8 年前

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的版本是不适用的。例如setunsetcompleteflush等方法在0.6.x版本中是无法使用的,参阅Meteoer的文档中心-Publish and subscribe可以比对出以上方法进行了修订。set方法设置为added方法,unset设置为removed方法,completeflush应该被合并为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();
  });
}
2 回复

恩,这个我之前也翻译过,现在翻译《DiscoverMeteor》

回到顶部