简体   繁体   English

WCF忽略webhttpbinding中的双工

[英]WCF ignore duplex in webhttpbinding

Hi i have an service looks something like this. 嗨,我有一项服务看起来像这样。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class Service : IService
{
    public string test(string value)
    {
        IServiceCallBack callback = OperationContext.Current.GetCallbackChannel<IServiceCallBack>();

        callback.callBackTest("callBack response");
        return value + ", normal response";
    }
}

[ServiceContract(CallbackContract = typeof(IServiceCallBack))]
public interface IService
{
    [OperationContract]
    [WebInvoke(
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        Method = "POST")]
    string test(string value);
}

public interface IServiceCallBack
{
    [OperationContract]
    void callBackTest(string value);
}

Now my needs are that two different bindings will use this same service (if possible) i know i can make two entire seperate services for this to work, but i rather not because the two bindings will use the same functions 现在,我的需要是两个不同的绑定将使用同一服务(如果可能),我知道我可以使两个完整的独立服务正常工作,但是我宁可不是因为两个绑定将使用相同的功能

My scenario is that we have some clients which is apple devices that will use an WebHttpBinding 我的情况是,我们有一些客户端,它们是将使用WebHttpBinding苹果设备。

And windows clients that will use NetTcpBinding 和将使用NetTcpBinding Windows客户端

Now i want the windows clients to be able to use the callback, but with the apple devices i just want to ignore the callback. 现在,我希望Windows客户端能够使用回调,但是对于苹果设备,我只想忽略回调。

if i try to host the service with the WebHttpBinding i get this error 如果我尝试使用WebHttpBinding托管服务, WebHttpBinding此错误

base = {"Contract requires Duplex, 
but Binding 'WebHttpBinding' doesn't 
support it or isn't configured properly to support it."}

To me this means that it wont work but can possibly be configured to work? 对我来说,这意味着它将无法正常工作,但可以将其配置为正常工作吗? or do they mean that i have to configure and remove my callback for this to work? 还是他们意味着我必须配置并删除我的回调才能正常工作?

So is it possible to ignore the callback for the WebHttpBinding and just receive the normal responses? 那么是否可以忽略WebHttpBinding的回调而只接收正常响应?

I solved this by editing the endpoint of the webhttpbinding by removing all info about the callback. 我通过删除有关回调的所有信息来编辑webhttpbinding的端点来解决此问题。 so now i have two working endpoints one with callbacks and they can share the same service code. 因此,现在我有两个工作的端点,其中一个具有回调,并且它们可以共享相同的服务代码。

the only downside is that i messed up my mex and i dont know how to solve that one but i made an workaround by not adding the webhttpbinding if you edit your settings that way. 唯一的缺点是我搞砸了mex,但我不知道如何解决这个问题,但如果您以这种方式编辑设置,则不通过添加webhttpbinding来解决问题。

Its not pretty but now i dont have to have two seperate services and duplicate code for all my wcf methods/operations. 它不是很漂亮,但是现在我不必为我的所有wcf方法/操作提供两个单独的服务和重复的代码。

public class WebServiceHost : IDisposable
{
    public WebServiceHost()
    {
        _tcpBaseAddress = "net.tcp://localhost:" + Globals.ClientTcpPort + "/V1";
        _httpBaseAddress = "http://localhost:" + Globals.ClientHttpPort + "/V1";

        List<Uri> addresses = new List<Uri>() { new Uri(_httpBaseAddress), new Uri(_tcpBaseAddress)};

        _host = new System.ServiceModel.Web.WebServiceHost(typeof(Service), addresses.ToArray());
        IsOpen = false;
    }

    readonly System.ServiceModel.Web.WebServiceHost _host;
    readonly string _httpBaseAddress;
    readonly string _tcpBaseAddress;

    public static bool IsOpen { get; set; }

    public void OpenHost()
    {
        try
        {
            //WebHttpBinding
            WebHttpBinding webBinding = new WebHttpBinding();
            webBinding.MaxBufferPoolSize = int.MaxValue;
            webBinding.MaxReceivedMessageSize = int.MaxValue;
            webBinding.Security.Mode = WebHttpSecurityMode.None;
            webBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;

            //NetTcpBinding
            NetTcpBinding tcpBinding = new NetTcpBinding();
            tcpBinding.MaxBufferPoolSize = int.MaxValue;
            tcpBinding.MaxReceivedMessageSize = int.MaxValue;
            tcpBinding.Security.Mode = SecurityMode.None;
            tcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;

            //ServiceBehavior
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpsGetEnabled = false;
            smb.HttpGetEnabled = true;

            _host.Description.Behaviors.Add(smb);

            ServiceDebugBehavior sdb = _host.Description.Behaviors.Find<ServiceDebugBehavior>();
            sdb.HttpHelpPageEnabled = Globals.IsDebugMode;
            sdb.HttpsHelpPageEnabled = Globals.IsDebugMode;
            sdb.IncludeExceptionDetailInFaults = Globals.IsDebugMode;

            UseRequestHeadersForMetadataAddressBehavior urhfmab = new UseRequestHeadersForMetadataAddressBehavior();
            _host.Description.Behaviors.Add(urhfmab);

            //MEX endpoint
            _host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexTcpBinding(), "mex");

            if (Globals.UseClientTcpHost && Globals.UseClientHttpHost)
            {
                _host.AddServiceEndpoint(typeof(IService), tcpBinding, _tcpBaseAddress);
                _host.AddServiceEndpoint(typeof(IService), webBinding, _httpBaseAddress);
                _host.Description.Endpoints[2].Contract = CopyContract(_host.Description.Endpoints[1].Contract);
            } 
            else if (Globals.UseClientTcpHost)
            {
                _host.AddServiceEndpoint(typeof(IService), tcpBinding, _tcpBaseAddress);
            }
            else if (Globals.UseClientHttpHost)
            {
                _host.AddServiceEndpoint(typeof(IService), webBinding, _httpBaseAddress);
                _host.Description.Endpoints[1].Contract = CopyContract(_host.Description.Endpoints[1].Contract);
            }

            _host.Open();
            IsOpen = true;

} }

Copy contract method 复制合同方式

private ContractDescription CopyContract(ContractDescription contract)
    {
        //ContractDescription orgContract = _host.Description.Endpoints[1].Contract;
        ContractDescription value = new ContractDescription("IServiceWithCallBack");

        //copy the value from orgiginal to the new contract.
        foreach (var item in contract.Behaviors)
        {
            value.Behaviors.Add(item);
        }

        value.ConfigurationName = contract.ConfigurationName;
        value.ContractType = contract.ContractType;

        foreach (var item in contract.Operations)
        {
            OperationDescription operation = new OperationDescription(item.Name, value);
            operation.BeginMethod = item.BeginMethod;

            foreach (var behavior in item.Behaviors)
            {
                operation.Behaviors.Add(behavior);
            }

            operation.EndMethod = item.EndMethod;

            foreach (var fault in item.Faults)
            {
                operation.Faults.Add(fault);
            }

            operation.IsInitiating = item.IsInitiating;
            operation.IsTerminating = item.IsTerminating;

            foreach (var knownType in item.KnownTypes)
            {
                operation.KnownTypes.Add(knownType);
            }

            foreach (var message in item.Messages)
            {
                operation.Messages.Add(message);
            }

            operation.ProtectionLevel = item.ProtectionLevel;
            operation.SyncMethod = item.SyncMethod;

            value.Operations.Add(operation);
        }

        value.ProtectionLevel = contract.ProtectionLevel;
        value.SessionMode = contract.SessionMode;

        List<OperationDescription> removeList = new List<OperationDescription>();

        foreach (var item in value.Operations)
        {
            if (item.Name.ToLower().EndsWith("callback"))
                removeList.Add(item);
        }

        foreach (var item in removeList)
        {
            value.Operations.Remove(item);
        }

        return value;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM