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
的版本是不适用的。例如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();
});
}
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);
}
});
});
});
解释
- 引入
ddp
模块:我们使用require('ddp')
引入 DDP 客户端库。 - 创建 DDP 客户端实例:使用
new DDPClient
创建一个 DDP 客户端实例,并指定连接的主机和端口。 - 事件监听:我们注册了几个事件监听器来处理连接成功、错误和消息接收的情况。
- 连接和订阅:调用
client.connect
方法建立连接,并在连接成功后订阅posts
集合的数据。 - 调用服务器方法:使用
client.call
调用服务器上的方法getPosts
,并在回调函数中处理结果。
注意事项
- 确保 Meteor 应用在
host
和port
指定的地址上运行。 - 如果需要在服务器上运行此代码,请确保 Node.js 环境中安装了所有必要的依赖。
- 如果需要调用服务器方法,确保服务器方法已经被定义并且可以从客户端调用。
通过这种方式,你可以在 Node.js 中使用 DDP 客户端与 Meteor 应用进行交互,实现数据的订阅和获取。