Aracılığıyla paylaş


Dayanıklı Çift Yönlü Bağıntı

Geri çağırma bağıntısı olarak da bilinen dayanıklı çift yönlü bağıntı, bir iş akışı hizmetinin ilk çağırana geri çağırma gönderme gereksinimi olduğunda kullanışlıdır. WCF çift yönlüden farklı olarak, geri çağırma gelecekte herhangi bir zamanda gerçekleşebilir ve aynı kanala veya kanal ömrüne bağlı değildir. Tek gereksinim, çağıranın geri çağırma iletisini dinleyen etkin bir uç noktaya sahip olmasıdır. Bu sayede iki iş akışı hizmeti uzun süre çalışan bir konuşmada iletişim kurabilir. Bu makalede, dayanıklı çift yönlü bağıntıya genel bir bakış sağlanır.

Dayanıklı Çift Yönlü Bağıntı Kullanma

Dayanıklı çift yönlü bağıntı kullanmak için, iki hizmetin veya WSHttpContextBindinggibi NetTcpContextBinding iki yönlü işlemleri destekleyen bağlam özellikli bir bağlama kullanması gerekir. Çağıran hizmet, istemcisinde Endpointistenen bağlamaya sahip bir ClientCallbackAddress kaydeder. Alıcı hizmet bu verileri ilk çağrıda alır ve ardından çağrı hizmetine geri çağrı yapan etkinlikte Send kendi başına Endpoint kullanır. Bu örnekte iki hizmet birbiriyle iletişim kurar. İlk hizmet, ikinci hizmette bir yöntem çağırır ve ardından yanıt bekler. İkinci hizmet geri çağırma yönteminin adını bilir, ancak bu yöntemi uygulayan hizmetin uç noktası tasarım zamanında bilinmez.

Not

Dayanıklı çift yönlü yalnızca uç nokta ile AddressingVersion yapılandırıldığında WSAddressing10kullanılabilir. Değilse, şu iletiyle bir InvalidOperationException özel durum oluşturulur: "İleti, AddressingVersion için uç nokta başvurusu içeren bir geri çağırma bağlamı üst bilgisi içeriyor. Geri çağırma bağlamı yalnızca AddressingVersion 'WSAddressing10' ile yapılandırıldığında iletilebilir."

Aşağıdaki örnekte, kullanarak WSHttpContextBindinggeri Endpoint çağırma oluşturan bir iş akışı hizmeti barındırılır.

// Host WF Service 1.
string baseAddress1 = "http://localhost:8080/Service1";
WorkflowServiceHost host1 = new WorkflowServiceHost(GetWF1(), new Uri(baseAddress1));

// Add the callback endpoint.
WSHttpContextBinding Binding1 = new WSHttpContextBinding();
host1.AddServiceEndpoint("ICallbackItemsReady", Binding1, "ItemsReady");

// Add the service endpoint.
host1.AddServiceEndpoint("IService1", Binding1, baseAddress1);

// Open the first workflow service.
host1.Open();
Console.WriteLine("Service1 waiting at: {0}", baseAddress1);

Bu iş akışı hizmetini uygulayan iş akışı, etkinliğiyle geri çağırma bağıntısını Send başlatır ve ile Sendilişkilendiren etkinlikten Receive bu geri çağırma uç noktasına başvurur. Aşağıdaki örnek, yönteminden GetWF1 döndürülen iş akışını temsil eder.

Variable<CorrelationHandle> CallbackHandle = new Variable<CorrelationHandle>();

Receive StartOrder = new Receive
{
    CanCreateInstance = true,
    ServiceContractName = "IService1",
    OperationName = "StartOrder"
};

Send GetItems = new Send
{
    CorrelationInitializers =
    {
        new CallbackCorrelationInitializer
        {
            CorrelationHandle = CallbackHandle
        }
    },
    ServiceContractName = "IService2",
    OperationName = "StartItems",
    Endpoint = new Endpoint
    {
        AddressUri = new Uri("http://localhost:8081/Service2"),
        Binding = new WSHttpContextBinding
        {
            ClientCallbackAddress = new Uri("http://localhost:8080/Service1/ItemsReady")
        }
    }
};

Receive ItemsReady = new Receive
{
    ServiceContractName = "ICallbackItemsReady",
    OperationName = "ItemsReady",
    CorrelatesWith = CallbackHandle,
};

Activity wf = new Sequence
{
    Variables =
    {
        CallbackHandle
    },
    Activities =
    {
        StartOrder,
        new WriteLine
        {
            Text = "WF1 - Started"
        },
        GetItems,
        new WriteLine
        {
            Text = "WF1 - Request Submitted"
        },
        ItemsReady,
        new WriteLine
        {
            Text = "WF1 - Items Received"
        }
     }
};

İkinci iş akışı hizmeti, sistem tarafından sağlanan, bağlam tabanlı bir bağlama kullanılarak barındırılır.

// Host WF Service 2.
string baseAddress2 = "http://localhost:8081/Service2";
WorkflowServiceHost host2 = new WorkflowServiceHost(GetWF2(), new Uri(baseAddress2));

// Add the service endpoint.
WSHttpContextBinding Binding2 = new WSHttpContextBinding();
host2.AddServiceEndpoint("IService2", Binding2, baseAddress2);

// Open the second workflow service.
host2.Open();
Console.WriteLine("Service2 waiting at: {0}", baseAddress2);

Bu iş akışı hizmetini uygulayan iş akışı bir Receive etkinlikle başlar. Bu alma etkinliği bu hizmet için geri çağırma bağıntısını başlatır, uzun süre çalışan çalışmanın benzetimini yapmak için bir süre geciktirir ve ardından hizmete ilk çağrıda geçirilen geri çağırma bağlamını kullanarak ilk hizmete geri çağrır. Aşağıdaki örnek, çağrısından GetWF2döndürülen iş akışını temsil eder. Etkinliğin Sendhttp://www.contoso.comyer tutucu adresi vardır; çalışma zamanında kullanılan gerçek adres, sağlanan geri arama adresidir.

Variable<CorrelationHandle> ItemsCallbackHandle = new Variable<CorrelationHandle>();

Receive StartItems = new Receive
{
    CorrelationInitializers =
    {
        new CallbackCorrelationInitializer
        {
            CorrelationHandle = ItemsCallbackHandle
        }
    },
    CanCreateInstance = true,
    ServiceContractName = "IService2",
    OperationName = "StartItems"
};

Send ItemsReady = new Send
{
    CorrelatesWith = ItemsCallbackHandle,
    Endpoint = new Endpoint
    {
        // The callback address on the binding is used
        // instead of this placeholder address.
        AddressUri = new Uri("http://www.contoso.com"),

        Binding = new WSHttpContextBinding()
    },
    OperationName = "ItemsReady",
    ServiceContractName = "ICallbackItemsReady"
};

Activity wf = new Sequence
{
    Variables =
    {
        ItemsCallbackHandle
    },
    Activities =
    {
        StartItems,
        new WriteLine
        {
            Text = "WF2 - Request Received"
        },
        new Delay
        {
            Duration = TimeSpan.FromMinutes(90)
        },
        new WriteLine
        {
            Text = "WF2 - Sending items"
        },
        ItemsReady,
        new WriteLine
        {
            Text = "WF2 - Items sent"
        }
     }
};

StartOrder yöntem ilk iş akışında çağrıldığında, iki iş akışı üzerinden yürütme akışını gösteren aşağıdaki çıkış görüntülenir.

Service1 waiting at: http://localhost:8080/Service1
Service2 waiting at: http://localhost:8081/Service2
Press enter to exit.
WF1 - Started
WF2 - Request Received
WF1 - Request Submitted
WF2 - Sending items
WF2 - Items sent
WF1 - Items Received

Bu örnekte, her iki iş akışı da kullanarak CallbackCorrelationInitializerbağıntıyı açıkça yönetir. Bu örnek iş akışlarında yalnızca tek bir bağıntı olduğundan, varsayılan CorrelationHandle yönetim yeterli olurdu.