Node DDP Client
A callback style DDP (Meteor's Distributed Data Protocol) node client, originally based alansikora's node-js_ddp-client and Meteor's python client. Uses a more callback style approach.
The client implements version 1 of DDP, as well as fallbacks to pre1 and pre2.
Installation
npm install ddp
Authentication
Built-in authentication support was removed in ddp 0.7.0 due to changes in Meteor version 0.8.2.
One can authenticate using plain-text logins as follows:
ddpclient.call("login", [
{ user : { email : "user@domain.com" }, password : "password" }
], function (err, result) { ... });
ddpclient.call("login", [
{ user : { username : "username" }, password : "password" }
], function (err, result) { ... });
You can also use vsivsi/ddp-login.
Example
Please see the example in examples/example.js
. Or here for reference:
var DDPClient = require("ddp");
var ddpclient = new DDPClient({
host : "localhost",
port : 3000,
ssl : false,
autoReconnect : true,
autoReconnectTimer : 500,
maintainCollections : true,
ddpVersion : '1',
useSockJs: true,
url: 'wss://example.com/websocket'
});
ddpclient.connect(function(error, wasReconnect) {
if (error) {
console.log('DDP connection error!');
return;
}
if (wasReconnect) {
console.log('Reestablishment of a connection.');
}
console.log('connected!');
setTimeout(function () {
ddpclient.call(
'deletePosts',
['foo', 'bar'],
function (err, result) {
console.log('called function, result: ' + result);
},
function () {
console.log('updated');
console.log(ddpclient.collections.posts);
}
);
}, 3000);
var Random = require("ddp-random"),
random = Random.createWithSeeds("randomSeed");
ddpclient.callWithRandomSeed(
'createPost',
[{ _id : random.id(),
body : "asdf" }],
"randomSeed",
function (err, result) {
console.log('called function, result: ' + result);
},
function () {
console.log('updated');
console.log(ddpclient.collections.posts);
}
);
ddpclient.subscribe(
'posts',
[],
function () {
console.log('posts complete:');
console.log(ddpclient.collections.posts);
}
);
var observer = ddpclient.observe("posts");
observer.added = function(id) {
console.log("[ADDED] to " + observer.name + ": " + id);
};
observer.changed = function(id, oldFields, clearedFields, newFields) {
console.log("[CHANGED] in " + observer.name + ": " + id);
console.log("[CHANGED] old field values: ", oldFields);
console.log("[CHANGED] cleared fields: ", clearedFields);
console.log("[CHANGED] new fields: ", newFields);
};
observer.removed = function(id, oldValue) {
console.log("[REMOVED] in " + observer.name + ": " + id);
console.log("[REMOVED] previous value: ", oldValue);
};
setTimeout(function() { observer.stop() }, 6000);
});
ddpclient.on('message', function (msg) {
console.log("ddp message: " + msg);
});
ddpclient.close();
ddpclient.on('socket-close', function(code, message) {
console.log("Close: %s %s", code, message);
});
ddpclient.on('socket-error', function(error) {
console.log("Error: %j", error);
});
var oid = new ddpclient.EJSON.ObjectID();
SockJS Mode
By using the useSockJs
option like below, DDP connection will use SockJs protocol to establish the WebSocket connection.
var ddpClient = new DDPClient({ useSockJs: true });
Meteor server uses SockJs to implement it's DDP server. With this mode, we can get the benefits provided by meteorhacks:cluster. Some of those are load balancing and service discovery.
- For load balancing you don't need to anything.
- For service discovery, just use the
path
option to identify the service you are referring to.
With this mode, path
option has a special meaning. So, thing twice before using path
option when you are using this option.
Unimplemented Features
The node DDP client does not implement ordered collections, something that while in the DDP spec has not been implemented in Meteor yet.
Thanks
Many thanks to Alan Sikora for the ddp-client which formed the inspiration for this code.
Contributions:
- Tom Coleman (@tmeasday)
- Thomas Sarlandie (@sarfata)
- Mason Gravitt (@emgee3)
- Mike Bannister (@possiblities)
- Chris Mather (@eventedmind)
- James Gill (@jagill)
- Vaughn Iverson (@vsivsi)