Compartilhar via


Como configurar a sincronização de n camadas

Este tópico mostra como configurar a sincronização de N camadas para Sync Framework. Os exemplos deste tópico focalizam os seguintes tipos do Sync Framework:

Para obter informações sobre como executar o código de amostra, consulte "Exemplo de aplicativos nos tópicos de instruções" em Programando tarefas comuns de sincronização do cliente e do servidor.

Noções básicas sobre sincronização de N camadas

Em uma arquitetura de sincronização de N camadas, os componentes de sincronização se espalham por várias camadas, como mostra a ilustração a seguir.

Topologia de sincronização de N camadas

Em uma arquitetura de duas camadas, todos os componentes residem no cliente, e este se comunica diretamente com o servidor. Em uma arquitetura de N camadas, o provedor de sincronização do servidor reside no servidor ou em outra camada, e a comunicação entre as camadas é tratada pelo objeto ServerSyncProviderProxy e um serviço, como um serviço Windows Communication Foundation (WCF). Um dos pontos fortes do Sync Framework é a facilidade com a qual é possível mover código de uma arquitetura de duas camadas para uma de N camadas. Se o código for fatorado de forma adequada, depois que você criar um serviço e adicionar um proxy, será necessária apenas uma pequena alteração no código do agente de sincronização. Os provedores de sincronização de cliente e servidor não precisam ser alterados.

Exemplo

Os exemplos de código a seguir mostram os principais componentes envolvidos em uma arquitetura de N camadas. São necessários componentes WCF adicionais. Esses componentes serão gerados se você usar o Visual Studio 2008. Para obter mais informações, consulte a documentação do Visual Studio.

Partes principais da API

Esta seção fornece exemplos de código que demonstram as semelhanças entre as sincronizações de duas e N camadas, além de destacar as partes principais da API usadas quando você está configurando a sincronização de N camadas. O exemplo de código a seguir é de uma classe derivada de SyncAgent. Para a sincronização de duas camadas, o provedor do cliente e o provedor do servidor são referenciados diretamente no agente de sincronização como provedores local e remoto.

this.LocalProvider = new SampleClientSyncProvider();

this.RemoteProvider = new SampleServerSyncProvider();
Me.LocalProvider = New SampleClientSyncProvider()

Me.RemoteProvider = New SampleServerSyncProvider()

O exemplo de código a seguir referencia o provedor do cliente diretamente, como no exemplo de duas camadas. Entretanto, o provedor remoto agora referencia um proxy em vez de referenciar diretamente o provedor do servidor. O proxy é criado passando-se uma referência para um serviço WCF.

this.LocalProvider = new SampleClientSyncProvider();

ServiceReference.ServiceForSyncClient serviceProxy = new ServiceReference.ServiceForSyncClient();
this.RemoteProvider = new ServerSyncProviderProxy(serviceProxy);
Me.LocalProvider = New SampleClientSyncProvider()

Dim serviceProxy As New ServiceReference.ServiceForSyncClient()
Me.RemoteProvider = New ServerSyncProviderProxy(serviceProxy)

Os exemplos de código a seguir criam provedores cliente e servidor. Esse código será idêntico se for usada uma arquitetura de duas ou N camadas.

public class SampleClientSyncProvider : SqlCeClientSyncProvider
{

    public SampleClientSyncProvider()
    {
        //Specify a connection string for the sample client database.
        Utility util = new Utility();
        this.ConnectionString = util.ClientConnString;
    }
}
public class SampleServerSyncProvider : DbServerSyncProvider
{
    public SampleServerSyncProvider()
    {
        //Create a connection to the sample server database.
        Utility util = new Utility();
        SqlConnection serverConn = new SqlConnection(util.ServerConnString);
        this.Connection = serverConn;

        //Create a command to retrieve a new anchor value from
        //the server.
        SqlCommand selectNewAnchorCommand = new SqlCommand();
        string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor;
        selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion() - 1";                                                         
        selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp);
        selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
        selectNewAnchorCommand.Connection = serverConn;
        this.SelectNewAnchorCommand = selectNewAnchorCommand;

        //Create a SyncAdapter for the Customer table manually, or
        //by using the SqlSyncAdapterBuilder as in the following
        //code.
        SqlSyncAdapterBuilder customerBuilder = new SqlSyncAdapterBuilder(serverConn);

        customerBuilder.TableName = "Sales.Customer";
        customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone";
        customerBuilder.SyncDirection = SyncDirection.DownloadOnly;
        customerBuilder.CreationTrackingColumn = "InsertTimestamp";
        customerBuilder.UpdateTrackingColumn = "UpdateTimestamp";
        customerBuilder.DeletionTrackingColumn = "DeleteTimestamp";
        
        SyncAdapter customerSyncAdapter = customerBuilder.ToSyncAdapter();
        customerSyncAdapter.TableName = "Customer";
        this.SyncAdapters.Add(customerSyncAdapter);
    }
}
Public Class SampleClientSyncProvider
    Inherits SqlCeClientSyncProvider

    Public Sub New()
        'Specify a connection string for the sample client database.
        Dim util As New Utility()
        Me.ConnectionString = util.ClientConnString

    End Sub
End Class
Public Class SampleServerSyncProvider
    Inherits DbServerSyncProvider

    Public Sub New()
        'Create a connection to the sample server database.
        Dim util As New Utility()
        Dim serverConn As New SqlConnection(util.ServerConnString)
        Me.Connection = serverConn

        'Create a command to retrieve a new anchor value from
        'the server.
        Dim selectNewAnchorCommand As New SqlCommand()
        Dim newAnchorVariable As String = "@" + SyncSession.SyncNewReceivedAnchor
        selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion()  1"
        selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp)
        selectNewAnchorCommand.Parameters(newAnchorVariable).Direction = ParameterDirection.Output
        selectNewAnchorCommand.Connection = serverConn
        Me.SelectNewAnchorCommand = selectNewAnchorCommand

        'Create a SyncAdapter for the Customer table manually, or
        'by using the SqlSyncAdapterBuilder as in the following
        'code.
        Dim customerBuilder As New SqlSyncAdapterBuilder(serverConn)

        customerBuilder.TableName = "Sales.Customer"
        customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone"
        customerBuilder.SyncDirection = SyncDirection.DownloadOnly
        customerBuilder.CreationTrackingColumn = "InsertTimestamp"
        customerBuilder.UpdateTrackingColumn = "UpdateTimestamp"
        customerBuilder.DeletionTrackingColumn = "DeleteTimestamp"

        Dim customerSyncAdapter As SyncAdapter = customerBuilder.ToSyncAdapter()
        customerSyncAdapter.TableName = "Customer"
        Me.SyncAdapters.Add(customerSyncAdapter)

    End Sub
End Class

O exemplo de código a seguir cria uma interface que o serviço implementa. A interface inclui os quatro métodos principais do provedor do servidor.

[ServiceContract]
public interface IServiceForSync
{
    [OperationContract()]
    SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);

    [OperationContract()]
    SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession);

    [OperationContract()]
    SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession);

    [OperationContract()]
    SyncServerInfo GetServerInfo(SyncSession syncSession);
}
<ServiceContract()> _
Public Interface IServiceForSync
    <OperationContract()> _
    Function ApplyChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal dataSet As DataSet, ByVal syncSession As SyncSession) As SyncContext

    <OperationContract()> _
    Function GetChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal syncSession As SyncSession) As SyncContext

    <OperationContract()> _
    Function GetSchema(ByVal tableNames As Collection(Of String), ByVal syncSession As SyncSession) As SyncSchema

    <OperationContract()> _
    Function GetServerInfo(ByVal syncSession As SyncSession) As SyncServerInfo
End Interface

O exemplo de código a seguir cria um serviço. Esse serviço implementa a interface que foi criada no exemplo de código anterior e referencia o provedor do servidor.

public class ServiceForSync : IServiceForSync
{

    private SampleServerSyncProvider _serverSyncProvider;

    public ServiceForSync()
    {
         this._serverSyncProvider = new SampleServerSyncProvider();
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession) {
        return this._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession) {
        return this._serverSyncProvider.GetChanges(groupMetadata, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession) {
        return this._serverSyncProvider.GetSchema(tableNames, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncServerInfo GetServerInfo(SyncSession syncSession) {
        return this._serverSyncProvider.GetServerInfo(syncSession);
    }       
}
Public Class ServiceForSync
    Implements IServiceForSync

    Private _serverSyncProvider As SampleServerSyncProvider


    Public Sub New()
        Me._serverSyncProvider = New SampleServerSyncProvider()
    End Sub


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function ApplyChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal dataSet As DataSet, ByVal syncSession As SyncSession) As SyncContext
        Return Me._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession)
    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal syncSession As SyncSession) As SyncContext
        Return Me._serverSyncProvider.GetChanges(groupMetadata, syncSession)

    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetSchema(ByVal tableNames As Collection(Of String), ByVal syncSession As SyncSession) As SyncSchema
        Return Me._serverSyncProvider.GetSchema(tableNames, syncSession)
    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetServerInfo(ByVal syncSession As SyncSession) As SyncServerInfo
        Return Me._serverSyncProvider.GetServerInfo(syncSession)
    End Function
End Class

Consulte também

Conceitos

Programando tarefas comuns de sincronização do cliente e do servidor