我必须创建一个示例项目,其中客户端和服务器通过 https(wss) 与 netHttpBinding 进行通信。我的代码和配置与 http 绑定工作得非常好。但是当我使用 HTTPS 时,它会给出如下错误
System.ServiceModel.CommunicationException:“向 https://localhost:8080/NetHttp 发出 HTTP 请求时发生错误。这可能是由于在 HTTPS 情况下未使用 HTTP.SYS 正确配置服务器证书。这也可能是由于客户端和服务器之间的安全绑定不匹配造成的。'
代码及配置如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace NetHttpBindingPocSvc
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract(CallbackContract = typeof(IDuplexServiceCallBack))]
public interface IHttpService
{
[OperationContract]
void SendMessage(string message);
}
public interface IDuplexServiceCallBack
{
[OperationContract]
void ReceiveMessage(string message);
}
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HttpService : IHttpService
{
public void SendMessage(string message)
{
Console.WriteLine($"Message from client received: {message}");
var callback = OperationContext.Current.GetCallbackChannel<IDuplexServiceCallBack>();
if (callback != null)
{
callback.ReceiveMessage("Message has been received");
}
}
internal class Program
{
static void Main(string[] args)
{
var serviceInstance = new ServiceHost(typeof(NetHttpBindingPocSvc.HttpService));
serviceInstance.Open();
Console.WriteLine($"Service is up and running");
Console.ReadLine();
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="netHttpBinding" />
<add scheme="https" binding="netHttpsBinding" />
</protocolMapping>
<services>
<service name="NetHttpBindingPocSvc.HttpService" behaviorConfiguration="netHttpBindingBehaviour">
<endpoint address="" binding="netHttpBinding" contract="NetHttpBindingPocSvc.IHttpService" bindingConfiguration="netHttpBinding">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:8080/NetHttp" />
<add baseAddress="http://localhost:8081/NetHttp"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netHttpBinding>
<binding name="netHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:40:00" sendTimeout="00:40:00"
transferMode="Buffered" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="20000000" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="20000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:40:00" enabled="false" />
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</netHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="netHttpBindingBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
internal class Program
{
static void Main(string[] args)
{
var message = Console.ReadLine();
string url = $"wss://localhost:8080/NetHttp";
var instanceContext = new InstanceContext(new DuplexMessageReceiver());
NetHttpService.HttpServiceClient client = new NetHttpService.HttpServiceClient(instanceContext);
client.Endpoint.Address = new System.ServiceModel.EndpointAddress(new Uri(url), EndpointIdentity.CreateDnsIdentity("localhost"));
//client.ClientCredentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My, System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "localhost");
client.Open();
client.SendMessage(message);
Console.ReadLine();
}
public class DuplexMessageReceiver : NetHttpService.IHttpServiceCallback
{
public void ReceiveMessage(string message)
{
Console.WriteLine(message);
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<system.serviceModel>
<bindings>
<netHttpBinding>
<binding name="NetHttpBinding_IHttpService">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
<webSocketSettings transportUsage="Always" />
</binding>
</netHttpBinding>
</bindings>
<client>
<endpoint address="wss://localhost:8080/NetHttp" binding="netHttpBinding"
bindingConfiguration="NetHttpBinding_IHttpService" contract="NetHttpService.IHttpService"
name="NetHttpBinding_IHttpService" />
</client>
</system.serviceModel>
</configuration>
我不确定我在这件事上做错了什么。相同的证书配置对于 net.tcp 绑定工作正常
尝试在这里修改它:
<client>
<endpoint address="wss://localhost:8080/NetHttp" binding="netHttpBinding"
bindingConfiguration="NetHttpBinding_IHttpService" contract="NetHttpService.IHttpService"
name="NetHttpBinding_IHttpService" />
<identity>
<dns value="localhost" />
</identity>
</client>
记得使用证书。