Source code of released version | Source code of development version
DDP (Distributed Data Protocol) is the stateful websocket protocol that Meteor uses to communicate between the client and the server. For more information about DDP, see the DDP project page or the DDP specification.
This package is used by nearly every Meteor application and provides a
main Meteor documentation page, under
"Publish and subscribe", "Methods", and "Server connections". Note in
particular that clients can use
DDP.connect to open a DDP
connection to any DDP service on the Internet.
ddp package provides both the DDP client and the server in the same package. We plan to separate it out into separate
ddp-server packages in the future. The client in
ddp works with all supported Isobuild architectures, including browsers (
web.browser.*), mobile devices (
web.cordova.*), and node.js (
os.*), using an appropriate transport for each. The server in
ddp only works under node.js at present, due to the lack of a good way to run a websocket server in the browser. Maybe one day this will change with WebRTC.
ddp supports the standard DDP transport, stringified EJSON over websockets. It also supports a second transport, EJSON over HTTP long polling. It will automatically fall back to this transport if websockets are not available. This is not as efficient as websockets, but it works in older browsers. It uses the sockjs library for long polling.
The sockjs-based long polling transport is not part of the official DDP standard. This is because, although sockjs works well, there is not a formal written standard for its behavior. It uses many different websocket emulation strategies for the widest possible browser compatibility, and standardizing all of these strategies would take a great deal of effort. Plus, websockets are widely available, so the need for this alternative transport will go away in the not-too-distant future. For now, if you are writing your own DDP implementation and want to interoperate with
ddp on old browsers that don't have websockets, just use sockjs directly.
When using the sockjs transport,
ddp has some special functionality to get around a limitation of long polling. Web browsers put a limit on the total number of HTTP connections that can be open to a particular domain at any one time, across all browser tabs. This is a potential problem for any app that uses long polling and that might be opened in multiple tabs. When too many tabs have been opened, the app can no longer connect to the server, since each of the tabs is holding open a long polling HTTP connection and the limit is hit. If this is an issue,
ddp can be configured to use a randomly generated subdomain for each long polling connection. This requires an appropriate wildcard DNS record on the server and appropriate proxy configuration. Meteor wires all of this up automatically when deploying an app with
Database driver integration.
ddp works well with the Mongo database drivers. For example, if you are using the
mongo package, then when you create a Mongo collection with
MyCollection = new Mongo.Collection("mycollection") on the client, the Mongo driver will automatically register with
ddp to receive incoming data for
mycollection and use it to keep
MyCollection up to date. In other words, it automatically wires up replication for all of your remote collections.
Automatic latency compensation.
ddp includes a full
implementation of fine-grained latency compensation, so users see
their screen update instantly when they make changes, without having
to wait for a server round trip. It will cooperate with any
full-stack DB drivers that are in use to snapshot and restore records
Transparent reconnection. If the DDP client loses its connection to the server, it will automatically reconnect, transparently to the application. Any subscriptions will be re-established and resynchronized without disturbing the application, and any outstanding method calls will be retried. However, this retrying could lead to duplicate method calls if the connection is lost after the server has received the method call, but before the client reads the result. This can be avoided just as it is with REST, by including a unique code as a parameter to the method. A future version of DDP will solve this on the protocol level (see Future Work).
ddp's authentication hooks work great with Meteor Accounts, a set of packages which provides a full suite of authentication functionality, from password-based accounts with email verification and password recovery, to OAuth login using services like Facebook and Twitter.
Input sanitization. On the server, you can use the
check function, provided by the match package, to easily validate the types of arguments passed by the client. Using a simple pattern language, you can also
check whether objects have the expected keps and array elements have the right type. In production code, add the audit-argument-checks package, and
ddp will make sure that every value passed from the client is validated with
check, and throw an exception if not. But be careful. The check only happens after the code has run, so while it will catch the vast majority of sanitization failures, it's not a perfect guarantee of safety.
ddp obeys the simple Tracker convention for transparent reactivity. Values such as the current connection status (are we online?), subscription readiness (is the
newsFeed done loading or should we show a progress indicator?), and the currently logged-in user (what username should we show in the status area at the top of page?) all work as reactive variables.
Default connection. Normally you open a DDP connection with
myconn = DDP.connect(url), and then work with the connection with calls like
myconn.call("transferBalance"). But if you build and deploy your app with the other Meteor tools, then a DDP server instance is automatically set up on the server, and each client is configured to automatically open a connection to that server on startup. You can work then with this "default connection" and "default server" with easy aliases like
Connection lifecycle hooks. Servers can run code when connections are established or closed. This can be used to update the database to show which users are online, making it easily to create presence features like a live-updating "Friends Online Now" list.
CRUD boilerplate and quickstart packages. The full-stack database drivers provide some helpful functionality that is worth mentioning here, even though it is actually part of those database packages, not
ddp. They provide general-purpose
delete methods for each database collection, so that it is not necessary to write methods for basic CRUD operations. A system of
deny rules is used to control what each user can do. And two "quickstart" packages are provided, for quick prototyping and to help new developers learn Meteor. The
insecure package turns off
deny rule checking for the generic
delete methods. The
autopublish package automatically subscribes every connected client to the full contents of every database collection.