diff --git a/packages/ddp/DDP.md b/packages/ddp/DDP.md index 0cb9d137f9..249be03c3e 100644 --- a/packages/ddp/DDP.md +++ b/packages/ddp/DDP.md @@ -7,7 +7,7 @@ DDP is a protocol between a client and a server that supports two operations: client informed about the contents of those documents as they change over time. -This document specifies the version "pre2" of DDP. It's a rough description of +This document specifies the version "1" of DDP. It's a rough description of the protocol and not intended to be entirely definitive. ## General Message Structure: @@ -21,6 +21,14 @@ DDP messages are JSON objects, with some fields specified to be EJSON. Each one has a `msg` field that specifies the message type, as well as other fields depending on message type. +The client and the server must ignore any unknown fields in messages. Future +minor revisions of DDP might add extra fields without changing the DDP version; +the client must therefore silently ignore unknown fields. However, the client +must not send extra fields other than those documented in the DDP protocol, in +case these extra fields have meaning to future servers. On the server, all +field changes must be optional/ignorable for compatability with older clients; +otherwise a new protocol version would be required. + ## Establishing a DDP Connection: ### Messages: @@ -324,3 +332,14 @@ behaves differently to the server, then syncing will fix this. * If both client and server support randomSeed, in the normal case the ids generated will be the same, and syncing will be a no-op. + + +## Version History + +```pre1``` was the first version of DDP + +```pre2``` added keep-alive (ping & pong messages), and randomSeed. + +```1``` should be considered the first official version of DDP. It is +currently identical to pre2, although non-incompatible changes may be made to +it in future. diff --git a/packages/ddp/livedata_common.js b/packages/ddp/livedata_common.js index 42e5da117b..1367d8d913 100644 --- a/packages/ddp/livedata_common.js +++ b/packages/ddp/livedata_common.js @@ -1,4 +1,6 @@ -SUPPORTED_DDP_VERSIONS = [ 'pre2', 'pre1' ]; +// All the supported versions (for both the client and server) +// These must be in order of preference; most favored-first +SUPPORTED_DDP_VERSIONS = [ '1', 'pre2', 'pre1' ]; LivedataTest.SUPPORTED_DDP_VERSIONS = SUPPORTED_DDP_VERSIONS; diff --git a/packages/ddp/livedata_connection_tests.js b/packages/ddp/livedata_connection_tests.js index dcee7378f7..06cff4b800 100644 --- a/packages/ddp/livedata_connection_tests.js +++ b/packages/ddp/livedata_connection_tests.js @@ -1407,6 +1407,40 @@ Tinytest.add("livedata connection - ping with id", function (test) { testGotMessage(test, stream, {msg: 'pong', id: id}); }); +_.each(LivedataTest.SUPPORTED_DDP_VERSIONS, function (version) { + Tinytest.addAsync("livedata connection - ping from " + version, + function (test, onComplete) { + var connection = new LivedataTest.Connection(getSelfConnectionUrl(), { + reloadWithOutstanding: true, + supportedDDPVersions: [version], + onDDPVersionNegotiationFailure: function () { test.fail(); onComplete(); }, + onConnected: function () { + test.equal(connection._version, version); + // It's a little naughty to access _stream and _send, but it works... + connection._stream.on('message', function (json) { + var msg = JSON.parse(json); + var done = false; + if (msg.msg === 'pong') { + test.notEqual(version, "pre1"); + done = true; + } else if (msg.msg === 'error') { + // Version pre1 does not play ping-pong + test.equal(version, "pre1"); + done = true; + } else { + Meteor._debug("Got unexpected message: " + json); + } + if (done) { + connection._stream.disconnect({_permanent: true}); + onComplete(); + } + }); + connection._send({msg: 'ping'}); + } + }); + }); +}); + var getSelfConnectionUrl = function () { if (Meteor.isClient) { return Meteor._relativeToSiteRootUrl("/");