WCF 和确认 - 我是否需要向客户发回“确定"? [英] WCF and confirmations - do I need to send back a 'OK got it' to client?

查看:20
本文介绍了WCF 和确认 - 我是否需要向客户发回“确定"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有成百上千的客户端计算机 WCP 连接到我的服务器,我是否应该以200 OK"类型的消息响应,说明我已成功接收数据并将其存储在数据库中?

If I have hundreds/thousands of client computers WCP'ing to my server, should I respond with a '200 OK' type message stating that I received the data and stored it in the db successfully?

这是否已经内置于 WCF 中?

Is this already built-into WCF?

推荐答案

这里提到了三种消息传递模式:

There are three messaging patterns mentioned here:

  1. 同步请求-响应
  2. 异步发送(使用单向服务即发即忘)
  3. 异步请求-响应(单向服务的双工服务调用)

所有三个都显示不同的消息传递行为,应根据您的需要选择要使用的模式.

All three display different messaging behaviour, and the pattern to be used should be chosen based on your needs.

对于在数据已持久化到数据库后向客户端返回成功的要求,选项 1 或 3 是合适的.

For your requirement of returning a success to the client when the data has been persisted to the database, options 1 or 3 are appropriate.

这是默认配置.

一旦服务完成所有任务,这将在同一个 http 连接上返回 200 响应.这意味着对服务的调用将在等待响应时阻塞 - 您的客户端将挂起,直到服务写入数据库并完成它需要的任何其他操作.

This returns a 200 response on the same http connection once the service has completed all its tasks. This means that calls to the service will block while waiting for the response - your client will hang until the service has written to the database and done anything else it needs.

只要传输层和消息基础设施层成功,就会返回 202 响应.返回的 202 表示消息已被接受.来自 http rfc:

Returns a 202 response so long as the transport layer and messaging infrastructure layer succeeds. The 202 returned indicates that the message has been accepted. From the http rfc:

请求已被接受进行处理,但处理尚未完成.(...) 202 响应是故意不置可否的.

The request has been accepted for processing, but the processing has not been completed. (...) The 202 response is intentionally non-committal.

这意味着一旦服务基础结构成功启动服务,您的客户端将继续执行,并且您不会收到有关数据库调用是否成功的信息.

This means that your client will continue execution as soon as the service infrastructure has successfully started the service, and you will receive no information about whether the database call succeeds or not.

与选项 2 类似,响应是 http 202,而不是 200,但是现在当您从客户端调用服务时,您提供了一个 InstanceContext 对象,该对象指定了一个对象来处理回调.客户端重新获得控制权,一个新线程异步等待通知您成功或失败的服务响应.

Similar to option 2, the response is an http 202, not a 200, but now when you call the service from the client you provide an InstanceContext object that specifies an object to handle the call back. The client regains control and a new thread waits asynchronously for the service response informing you of success or failure.

以下是有关在 WCF 中实现这些模式的更多信息.写完后,它很长,但有一些有用的注释和代码.

Below is some more info about implementing these patterns in WCF. After writing it, it is pretty long but there are a couple of useful comments as well as the code.

正如 Whisk 提到的,Juval Lowy 有一篇文章涵盖了很多这个细节(以及更多!)这里

As Whisk mentioned, Juval Lowy has an article covering a lot this detail (and more!) here

这是 WCF 中的默认行为,因此您无需执行任何操作 - 它适用于许多不同的绑定,包括 wsHttpBinding 和 basicHttpBinding.

This is the default behaviour in WCF so you should not need to do anything - it works with lots of different bindings including wsHttpBinding and basicHttpBinding.

需要注意的一点是,即使您有一个像这样的空操作,您的客户端挂起等待 200 响应也会发生所描述的行为:

One thing to note is that the behaviour described with your client hanging waiting for the 200 response occurrs even if you have a void Operation like so:

[ServiceContract]
interface IMyServiceContract
{
    [OperationContract]       
    void DoSomeThing(InputMessage Message);
}

选项 2

要将操作设置为单向,您只需将其装饰如下:

Option 2

To set an operation as one-way you simply decorate it as so:

[ServiceContract]
interface IMyServiceContract
{
    [OperationContract(IsOneWay = true)]       
    void DoSomeThing(InputMessage Message);
}

以这种方式修饰的方法只能有一个 void 返回类型.一个问题是该服务会很高兴地构建,并且在您连接到它之前,您不会收到说服务配置无效的异常.

Methods decorated in this way must only have a return type of void. One gotcha is that the service will happily build and you won't get an exception saying the service config is invalid until you connect to it.

创建双工回调服务的接口代码为:

The interface code for creating a duplex callback service is:

[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
interface IMyContract
{
    [OperationContract(IsOneWay=true)]       
    void DoSomeThing(InputMessage Message);
}

public interface IMyContractCallback
{
    [OperationContract(IsOneWay = true)]
    void ServiceResponse(string result);      
}

在客户端,你需要类似的东西来设置回调:

And on the client side you need something like so to set up the callback:

public class CallbackHandler : IMyContractCallback        
{
    #region IEchoContractCallback Members

    public void ServiceResponse(string result)
    {
        //Do something with the response
    }

    #endregion
}

// And in the client when you set up the service call:

InstanceContext instanceContext = new InstanceContext(new CallbackHandler());
MyContractClient client = new MyContractClient(instanceContext);

InputMessage msg = new InputMessage();

client.DoSomething(msg);           

在服务中,您可能会有一些代码,例如:

In the service you would perhaps have some code like:

class MyContractImplementation : IMyContract
{
    public void DoSomeThing(MyMessage Message)
    {

        string responseMessage;

        try
        {
           //Write to the database
           responseMessage = "The database call was good!";
        }
        catch (Exception ex)
        {
            responseMessage = ex.Message;
        }

        Callback.ServiceResponse(responseMessage);
    }
}

要注意的一件重要的事情,一开始让我感到困惑,就是要小心异常.如果你:

One important thing to note, that caught me out at first, is to be careful about exceptions. If you:

  • 消费一个异常,你不会得到错误警告(但回调会发生)

  • Consume an exception, you will get no warning of the error (but the callback will happen)

抛出一个未处理的异常,服务将终止,客户端甚至不会得到回调.

Throw an unhandled exception, the service will terminate and the client will not even get the callback.

这是该方法与选项 1 相比的一大缺点,选项 1 会在抛出未处理的异常时返回异常.

That is one big disadvantage of this method compared with Option 1, Option 1 will return the exception when an unhandled exception is thrown.

这篇关于WCF 和确认 - 我是否需要向客户发回“确定"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆