TODO |
177 |
describe sync anchors
Have a look at the SyncML spec
http://www.openmobilealliance.org/tech/affiliates/syncml/syncmlindex.html
to find out more.
4) Changes and Timestamps
@todo description of Changes and Timestamps, "mirroring effect"
This is real tricky stuff.
First it's important to know, that the SyncML protocol requires the
ending timestamp of the sync timeframe to be exchanged _before_ the
actual syncing starts. So all changes made during a sync have timestamps
that are in the timeframe for the next upcoming sync. Data exchange in
a sync session works in two steps: 1st) the clients sends its changes to
the server, 2nd) the server sends its changes to the client.
So when in step 2, the backend datastore API is called with a request
like "give me all changes in the server since the last sync". Thus you
also get the changes induced by the client in step 1 as well. You have
to somehow "tag" them to avoid echoing (and thus duplicating) them back
to the client. Simply storing the guids in the session is not
sufficient: the changes are made _after_ the end timestamp (see 1) of
the current sync so you'll dupe them in the next sync.
The current implementation deals with this as follows: whenever a client
induced change is done in the backend, the timestamp for this change is
stored in the cuid<->suid map in an additional field. That's the perfect
place as the tagging needs to be done "per client device": when an add
is received from the PDA it must not be sent back as an add to this
device, but to mobile phone it must be sent.
This is sorted out during the getServerChanges() process: if a server
change has a timestamp that's the same as in the guid<->suid map, it
came from the client and must not be added to the list of changes to be
sent to this client.
See the description of Horde_SyncMl_Backend_Sql::_getChangeTS() for some
more information.
5) Messages and Packages
A message is a single HTTP Request. A package is single "logical
message", a sync step. Normally the two coincide. However due to message
size restrictions one package may be transferred in multiple messages
(HTTP requests).
7) Server mode, client mode and test mode
Per default, a backend is used for an SyncML server. Regarding the
SyncML protocol, the working of client and server is similar, except
that
a) the client initiates the sync requests and the server respons to them,
and
b) the server must maintain the client id<->server id map.
Currently the Horde_SyncMl package is designed to create servers. But
is's an obvious (and straightforward) extension to do it for clients as
well. And as a client has actually less work to do than a server, the
backend should work for servers _and_ clients. During the sessionStart(),
the backend gets a parameter to let it know whether it's in client or
server mode (or test, see below). When in client mode, it should behave
slightly different:
a) the client doesn't do suid<->cuid mapping, so all invokations to the
map creation method createUidMap().
b) the client has only client ids, no server ids. So all arguments are
considered cuids even when named suid. See the Horde_SyncMl_Backend_Sql
implementation, it's actually not that difficult.
Finally there's the test mode. The test cases consist of replaying
pre-recorded sessions. For that to work, the test script must "simulate"
user entries in the server data store. To do so, it creates a backend in
test mode. This behaves similar to a client: when an server entry is
created (modified) using addEntry() (replaceEntry()), no map entry must
be done.
The test backend uses also the two methods testSetup() and testTearDown()
to create a clean (empty) enviroment for the test user "syncmltest". See
the Horde_SyncMl_Backend_Sql implementation for details.
Copyright 2005-2017 Horde LLC (http://www.horde.org/)
See the enclosed file LICENSE for license information (LGPL). If you
did not receive this file, see http://www.horde.org/licenses/lgpl21. |