[英]WCF ignore duplex in 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
Windows客戶端
現在,我希望Windows客戶端能夠使用回調,但是對於蘋果設備,我只想忽略回調。
如果我嘗試使用WebHttpBinding
托管服務, WebHttpBinding
此錯誤
base = {"Contract requires Duplex,
but Binding 'WebHttpBinding' doesn't
support it or isn't configured properly to support it."}
對我來說,這意味着它將無法正常工作,但可以將其配置為正常工作嗎? 還是他們意味着我必須配置並刪除我的回調才能正常工作?
那么是否可以忽略WebHttpBinding
的回調而只接收正常響應?
我通過刪除有關回調的所有信息來編輯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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.