Sync Mobile clients with Microsoft Sync Framework 4.0
Complete walkthrough on creating sync services and consuming through a windows mobile 6.5 pda device without requiring to install sync framework on pda itself.
sync.png
image source: microsoft.com
About Microsoft Sync Framework 4.0 October 2010 CTP:
The Microsoft Sync Framework 4.0 October 2010 CTP is built on top of Sync Framework 2.1. It defines Odata + Sync, a sync protocol that makes it easy to build offline applications on any client platform capable of caching data. With Sync framework 4.0, client does not required sync framework installed as compared to earlier versions of Sync Framework which required Windows systems with Sync Framework runtime installed. This makes possible to use sync services on lots of client devices(windows mobile, windows phone 7, iphone, android, silverlight client, etc)
How to create services for sql server.
Your first action to configure a database for synchronization is to define a scope that defines what you want to synchronize. that, you provision the database to create a change-tracking and metadata management infrastructure that consists of metadata tables, triggers, and stored procedures. Microsoft sync framework 4.0 ctp comes with a tool called SyncSvcUtil.exe to configure sync services.
SyncSvcUtil requires xml file to configure. Xml file is a configuration file that defines which database to use, scopes with one or many tables and filters.
Sample config file:
Provision Database
Command line to provision the db
SyncSvcUtil /mode:provision /scopeconfig:dbconfig.config
Create service classes
SyncSvcUtil /mode:codegen /target:server /scopeconfig:dbconfig.config
This command line creates services, entities that can be hosted on the IIS. For each scope it creates 2 files(service class and entity class). Entity class is the exact representation of database tables. You must make some changes to the services initialization method and you are ready to host the server. You service is completed. Every time you change the tables(add/remove columns,tables) first deprovision the db and do provisioning again.
What to include on the service initialization class.
- Set the connection string (you usually map this to web.config).
- Add filter parameters if any.
Sample initalization code of DefaultScopeSyncService.svc.cs
public static void InitializeService(Microsoft.Synchronization.Services.ISyncServiceConfiguration config) {
// TODO: MUST set these values
config.ServerConnectionString = ConfigurationManager.ConnectionStrings["DbConnectionString"].ToString();
config.SetEnableScope("DefaultScope");
config.AddFilterParameterConfiguration("userid", "items", "@userid", typeof(System.Guid));
//
//
// TODO: Optional.
// config.UseVerboseErrors = true;
// config.EnableDiagnosticPage = true;
// config.SetDefaultSyncSerializationFormat(Microsoft.Synchronization.Services.SyncSerializationFormat.ODataJson);
// config.SetConflictResolutionPolicy(Microsoft.Synchronization.Services.ConflictResolutionPolicy.ServerWins);
}
Using sync services on client.
Since client don't use any sync framework as in previous pervious, you have to code db operation for each table yourself. Sample files included on the Sync Framework 4.0 CTP can be a basic guide to start with.
Sync workflow
Lets see how it works. First time every client sync gets all the row from the server and inserts on the clients database. Server also sends binary key to the client to change tracking each time client requests for changes. You must store that key on the client side and send every time you send request to the server for changes. This key is tracked on the server for incremental changes.
Each table on the client side contains IsDirty,IsTombstone,MetadataInfo to handle client side changes. Modification on the client side set IsDirty to the row. Every time you sync with server, you first get records for each table which are dirty and send to server for upload. Server handles them automatically.If server sends success synchronization, you reset the rows with IsDirty=0 so that next time client don't resend them. Deletes are handles by IsTombstone. If you delete records on the client, you should not hard delete it, should set to IsTombstone=1 and IsDirty=1. Changes set sent to the server with IsTombstone=1 are considered deleted and server deletes them. After response from the server of successful sync also delete from the client whose rows are IsTombstone=1.
My own customization on client side.
One of my client wants to something different when user deletes rows on the client. He wants to delete on the client but not on the server so that if clients wants again he can download later. He wants to hard delete on the client and stay available on the server side. The default sync workflow does not suppers this.
So i did some trick to make it work.
I added a field called ClientDeleted on each table (both on server and client tables). I added one more filter for the ClientDeleted filed on each table.
When i delete the row on the client side i just set the ClientDeleted=1 and IsDirty=1 (IsTombstone is still 0). Putting IsTombstone=0 is to remain the row on the server. Then i send the change-sets to the server. Server treats this as a changed row rather than deleted. On response from the server, on the client side, i hard delete the rows that are set ClientDeleted=1. To Prevent the downloading of Clientdeleted rows on the client on next syncs, i only download the rows from the server that are ClientDeleted=0. OffCourse clients can