2015-01-23 3 views
0

Привет, у меня есть служба выглядит примерно так.WCF игнорировать дуплекс в webhttpbinding

[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); 
} 

Теперь мои потребности, что два различных привязки будут использовать ту же самую услугу (если это возможно) я знаю, что я могу сделать целых два раздельных услуги для этой работы, но я скорее не потому, что два привязок будут использовать те же функции

Мой сценарий является то, что у нас есть клиенты, которые яблочно устройства, которые будут использовать клиент WebHttpBinding

и окна, которые будут использовать NetTcpBinding

Теперь я хочу клиент окна в иметь возможность использовать обратный вызов, но с яблочными устройствами я просто хочу игнорировать обратный вызов.

если я пытаюсь разместить службу с WebHttpBinding я получаю эту ошибку

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

Для меня это означает, что она не будет работать, но, возможно, может быть настроена на работу? , или они означают, что мне нужно настроить и удалить мой обратный вызов для этого?

Так можно ли игнорировать обратный вызов для WebHttpBinding и просто получать нормальные ответы?

+1

HTTP по своей природе не является дуплекс - единственный дуплексный HTTP привязки в WCF является 'DualWsHttpBinding'. Я думаю, что самый простой способ для вас в этом случае - создать две службы - одну, которая выполняет обратные вызовы, а другая - нет. – Tim

ответ

0

Я решил это, отредактировав конечную точку webhttpbinding, удалив всю информацию о обратном вызове. поэтому теперь у меня есть две рабочие конечные точки с обратными вызовами, и они могут использовать один и тот же служебный код.

Единственный недостаток в том, что я испортил свой mex, и я не знаю, как решить эту проблему, но я сделал обходное решение, не добавляя webhttpbinding, если вы отредактируете свои настройки таким образом.

Его не очень, но теперь мне не нужно иметь две отдельные службы и дублировать код для всех моих методов/операций 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; 

}

Копия метод контракта

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; 
    } 
Смежные вопросы