From c5a643c9f04b423fdbacb8c57b0ed7ee467eccf6 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Thu, 28 Aug 2014 09:09:46 -0700 Subject: [PATCH 1/4] Add notes about adding/ignoring fields in DDP --- packages/livedata/DDP.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/livedata/DDP.md b/packages/livedata/DDP.md index 0cb9d137f9..7172c5e955 100644 --- a/packages/livedata/DDP.md +++ b/packages/livedata/DDP.md @@ -21,6 +21,15 @@ 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. +Extra fields may be included by the client and the server; this must not be an +error. 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 here +or in future versions, 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: From 24ea12b1e182dc3e269994b5ac9a6cde3985fa50 Mon Sep 17 00:00:00 2001 From: Justin SB Date: Thu, 28 Aug 2014 09:16:31 -0700 Subject: [PATCH 2/4] Add a DDP version label of 1, currently identical to pre2 --- packages/livedata/DDP.md | 13 ++++++++++++- packages/livedata/livedata_common.js | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/livedata/DDP.md b/packages/livedata/DDP.md index 7172c5e955..cbf0d4b71a 100644 --- a/packages/livedata/DDP.md +++ b/packages/livedata/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: @@ -333,3 +333,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/livedata/livedata_common.js b/packages/livedata/livedata_common.js index 42e5da117b..1367d8d913 100644 --- a/packages/livedata/livedata_common.js +++ b/packages/livedata/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; From b9e357bc8f1c9a4a649a54bfaf8f2a977e18806e Mon Sep 17 00:00:00 2001 From: Justin SB Date: Thu, 28 Aug 2014 09:21:26 -0700 Subject: [PATCH 3/4] Tighten up the language around minor revisions --- packages/livedata/DDP.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/livedata/DDP.md b/packages/livedata/DDP.md index cbf0d4b71a..249be03c3e 100644 --- a/packages/livedata/DDP.md +++ b/packages/livedata/DDP.md @@ -21,14 +21,13 @@ 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. -Extra fields may be included by the client and the server; this must not be an -error. 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 here -or in future versions, 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. +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: From c1f081d2b12a4863f93ead64333d670e44e9b99f Mon Sep 17 00:00:00 2001 From: Justin SB Date: Thu, 28 Aug 2014 11:16:57 -0700 Subject: [PATCH 4/4] Test ping-pong from different client versions --- .../livedata/livedata_connection_tests.js | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/livedata/livedata_connection_tests.js b/packages/livedata/livedata_connection_tests.js index dcee7378f7..06cff4b800 100644 --- a/packages/livedata/livedata_connection_tests.js +++ b/packages/livedata/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("/");