Nodejs Meteor-DDP 使用问题

Nodejs Meteor-DDP 使用问题

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();
  });
}

4 回复

Nodejs Meteor-DDP 使用问题

DDP

DDP(Distributed Data Protocol)是一种用于实时双向通信的协议,它使得客户端能够与服务器进行实时数据交换。DDP的详细规范可以在Meteor的官方文档中找到。

初始化应用

我们可以通过Meteor快速构建一个简单的项目 app,并查看生成的文件结构:

meteor create app
cd app
meteor remove autopublish
meteor

生成的目录结构如下:

app
├── .meteor
├── app.css
├── app.html
└── app.js

app.html

<head>
  <title>app</title>
</head>

<body>
  posts
  {{> posts}}
</body>

<template name="posts">
  <ul>
    {{#each posts}}
      <li>{{message}}</li>
    {{/each}}
  </ul>
</template>

app.js

Posts = new Meteor.Collection('posts');

if (Meteor.isClient) {
  Template.posts.helpers({
    posts() {
      return Posts.find();
    }
  });

  Meteor.subscribe('posts', [], function() {
    console.log('[client] -- posts订阅完毕');
  });
}

if (Meteor.isServer) {
  Meteor.startup(() => {
    Posts.remove({});
    for (let i = 1; i <= 3; i++) {
      Posts.insert({ message: '消息' + i });
    }
  });

  Meteor.publish('posts', function() {
    return Posts.find();
  });
}

Node-DDP

接下来,我们使用Node.js构建一个DDP客户端。首先,在 app 同级目录下创建一个名为 node-client 的文件夹,进入该文件夹并通过 npm 安装所需的模块:

npm install -d ddp

创建 client.js 文件,并编写以下代码:

const DDPClient = require('ddp');

const client = new DDPClient({
  host: 'localhost',
  port: 3000
});

client.on('message', function(data, flags) {
  console.log('[DDP消息]: ', data);
});

client.connect(function() {
  client.subscribe('posts', [], function() {
    console.log('[posts订阅完毕]');
  });
});

运行该脚本:

node /node-client/client.js

在浏览器端使用Meteor-DDP

为了在浏览器端使用DDP,我们可以使用第三方库 Meteor-DDP。首先,下载 Meteor-DDP 并将其添加到项目中。

方式一:将 meteor-ddp.js 放置在 public 目录下

<script type="text/javascript" src="/meteor-ddp.js"></script>

方式二:将 Meteor-DDP 打包成Meteor的包

(function(window) {
  // meteor-ddp.js源码全部复制到这
  window.MeteorDdp = MeteorDdp;
})(window);

然后在 app.js 中使用 MeteorDdp

if (Meteor.isClient) {
  const ddp = new MeteorDdp('ws://127.0.0.1:3000/websocket');
  
  ddp.connect().then(function() {
    console.log('[DDP Connected]');
    ddp.subscribe('posts', []).catch(function() {
      console.log('[client posts subscription failed]');
    });
  });

  var Posts = new Meteor.Collection('posts');
  Template.posts.helpers({
    posts() {
      return Posts.find();
    }
  });

  Meteor.subscribe('posts', [], function() {
    console.log('posts已订阅');
  });
}

if (Meteor.isServer) {
  Meteor.publish('posts', function() {
    const me = this;
    for (let i = 1; i <= 3; i++) {
      me.added('posts', Meteor.uuid(), { message: '消息' + i });
    }
    me.ready();
  });
}

以上就是如何使用Node.js和Meteor-DDP实现客户端与服务器之间的实时数据交换。


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

在处理 Nodejs Meteor-DDP 使用问题 这个问题时,我们需要关注如何在 Node.js 中使用 DDP 协议与 Meteor 应用进行通信。以下是一个简单的示例,展示了如何使用 ddp 模块连接到 Meteor 应用并订阅数据。

示例代码

假设我们已经有一个 Meteor 应用,并且它在本地的 3000 端口运行。我们将在另一个 Node.js 进程中使用 DDP 客户端来连接这个 Meteor 应用并订阅 posts 集合的数据。

创建 DDP 客户端

// 文件: /node-client/client.js
const DDPClient = require('ddp');

const client = new DDPClient({
  host: 'localhost',
  port: 3000,
});

client.on('connected', () => {
  console.log('DDP Client connected to Meteor server');
});

client.on('error', (err) => {
  console.error('DDP Client error:', err);
});

client.on('message', (msg) => {
  console.log('Received message from server:', msg);
});

client.connect(() => {
  client.subscribe('posts', [], () => {
    console.log('Subscribed to posts collection');
    client.call('getPosts', (err, result) => {
      if (err) {
        console.error('Failed to get posts:', err);
      } else {
        console.log('Fetched posts:', result);
      }
    });
  });
});

解释

  1. 引入 ddp 模块:我们使用 require('ddp') 引入 DDP 客户端库。
  2. 创建 DDP 客户端实例:使用 new DDPClient 创建一个 DDP 客户端实例,并指定连接的主机和端口。
  3. 事件监听:我们注册了几个事件监听器来处理连接成功、错误和消息接收的情况。
  4. 连接和订阅:调用 client.connect 方法建立连接,并在连接成功后订阅 posts 集合的数据。
  5. 调用服务器方法:使用 client.call 调用服务器上的方法 getPosts,并在回调函数中处理结果。

注意事项

  • 确保 Meteor 应用在 hostport 指定的地址上运行。
  • 如果需要在服务器上运行此代码,请确保 Node.js 环境中安装了所有必要的依赖。
  • 如果需要调用服务器方法,确保服务器方法已经被定义并且可以从客户端调用。

通过这种方式,你可以在 Node.js 中使用 DDP 客户端与 Meteor 应用进行交互,实现数据的订阅和获取。

回到顶部