Я работаю над проектом клиент-сервер, в котором клиенты развертываются через Интернет. Все службы написаны в WCF и используют wsHttpBinding
. Мне нужно реализовать функцию обратного вызова клиента, и поскольку клиенты находятся за брандмауэрами и NAT, мне говорят, что я могу использовать netTcpBinding
, который обходит брандмауэр/NAT. Поэтому я создал службу и контракт обратного вызова.Служба WCF net.tcp по проблеме IIS
На стороне клиента, это то, как я пытаюсь подключиться к нему:
var binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.MaxReceivedMessageSize = Int32.MaxValue;
binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
AuthorizationToken authorizationToken =
new AuthorizationToken(Session.Current.Username, Session.Current.Password, RequiredPermission.User);
using (DuplexChannelFactory<INotificationService> channel =
new DuplexChannelFactory<INotificationService>(new InstanceContext(this), binding,
new EndpointAddress("net.tcp://mywebsite.com:808/MyServices/NotificationService.svc")))
{
channel.Credentials.UserName.UserName = authorizationToken.FormatTokenForTransmission();
channel.Credentials.ServiceCertificate.Authentication.CertificateValidationMode =
System.ServiceModel.Security.X509CertificateValidationMode.None;
INotificationService proxy = channel.CreateChannel();
proxy.Subscribe();
}
код почти идентичен коду, который подключается к wsHttpBinding
услуг для типа связывания и ChannelFactory
исключением. web.config
также выглядит следующим образом:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpConfig" maxReceivedMessageSize="2147483647">
<security mode="Message" >
<message clientCredentialType="UserName"/>
</security>
<readerQuotas maxArrayLength="2147483647"/>
</binding>
</wsHttpBinding>
<netTcpBinding>
<binding name="netTcpConfig">
<security mode="Message" >
<message clientCredentialType="UserName"/>
</security>
<readerQuotas maxArrayLength="2147483647"/>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="MyProject.Services.NotificationService" behaviorConfiguration="authenticationBehavior">
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpConfig"
contract="MyProject.ServiceContracts.INotificationService" />
<endpoint address="mex"
binding="mexTcpBinding"
bindingConfiguration=""
name="MyServiceMexTcpBidingEndpoint"
contract="IMetadataExchange" />
</service>
// other non-net.tcp services go here
</services>
<behaviors>
<serviceBehaviors>
<behavior name="authenticationBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceCredentials>
<serviceCertificate findValue="SomeCertificate" storeLocation="LocalMachine"
storeName="TrustedPeople" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MyProject.Authentication.CustomAuthenticator, MyProject.Authentication" />
</serviceCredentials>
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Когда я делаю вызов службы, запрос действительно добраться до IIS
, но исключения без сообщения внутреннего исключения, и на стороне сервера, я получаю следующий след войти:
The socket connection was aborted. This could be caused by an error processing
your message or a receive timeout being exceeded by the remote host, or an underlying
network resource issue. Local socket timeout was '00:01:00
Я понимаю, что это очень общая ошибка, и мой вопрос, вы видите что-то неправильно с моими настройками веб-конфигурации? Любая помощь приветствуется.
Все службы net.tcp запущены. IIS настроен на прием tcp, как я уже сказал, запрос действительно попадает в IIS. Порт открыт, дважды проверен. Я не занимаюсь таймаутом, поскольку реализация службы просто записывает сообщение в журнал событий. – user2872534
Когда вы говорите, что служба записывает сообщение в журнал событий. Не могли бы вы быть конкретными. Можете ли вы провести переговоры и поделиться своими выводами. Единственная причина, по которой я говорю, что это может быть проблема в сети, потому что вы получаете прерывание сокета .. – codingpirate
В реализации службы я просто делаю вызов 'EventLog.WriteEntry()'. Это, очевидно, не займет 1 минуту, поэтому тайм-аут не имеет значения. – user2872534