#c# #wcf #app-config #named-pipes
#c# #wcf #app-config #именованные каналы
Вопрос:
Я разочарован. Хорошо, вот ошибка.
В net.pipe не было прослушиваемой конечной точки://localhost/MyIpcAppToService, которая могла бы принять сообщение. Это часто вызвано неправильным адресом или действием SOAP. Смотрите InnerException, если оно присутствует, для получения более подробной информации.
Я наконец-то заработал файл App.Config, по крайней мере, жалоб нет.
Текущее приложение.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyService.Communication.IpcAppToService">
<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" />
</protocolMapping>
<bindings>
<wsDualHttpBinding>
<!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
<binding name="MyAppToServiceEndpointBinding"
transactionFlow="true"
sendTimeout="00:01:00"
maxReceivedMessageSize="2147483647"
messageEncoding="Mtom">
</binding>
</wsDualHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://localhost:8733"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
<appSettings>
<add key="countoffiles" value="7"/>
<add key="logfilelocation" value="abc.txt"/>
</appSettings>
</configuration>
Раньше у меня был:
<endpoint address="http://localhost:8733/MyIpcAppToService" ...
и в событии службы Windows OnStart()
:
(начиная с этого вопроса, следующий код теперь закомментирован, поскольку App.config
файл должен запускать named.pipe.)
public Boolean CreatePipeServer()
{
string eventText = $"My Service: CommAppToService::CreatePipeServer(IPC App to Service){Environment.NewLine}";
try
{
if (null != this.ServiceParent.HostIpcAppToService)
this.ServiceParent.HostIpcAppToService = null;
string pipeBaseAddress = @"net.pipe://localhost/MyIpcAppToService";
this.ServiceParent.HostIpcAppToService = new ServiceHost(typeof(IpcAppToService), new Uri(pipeBaseAddress));
NetNamedPipeBinding pipeBinding = new NetNamedPipeBinding()
{
//ReceiveTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
//SendTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
};
this.ServiceParent.HostIpcAppToService.AddServiceEndpoint(typeof(IIpcAppToService), pipeBinding, "MyIpcAppToService");
this.ServiceParent.HostIpcAppToService.UnknownMessageReceived = HostIpcAppServer_UnknownMessageReceived;
this.ServiceParent.HostIpcAppToService.Faulted = HostIpcAppServer_Faulted;
this.ServiceParent.HostIpcAppToService.Closing = HostIpcAppServer_Closing;
this.ServiceParent.HostIpcAppToService.Closed = HostIpcAppServer_Closed;
this.IpcAppToService = new IpcAppToService();
this.IpcAppToService.ApplyDispatchBehavior(this.ServiceParent.HostIpcAppToService);
this.IpcAppToService.Validate(this.ServiceParent.HostIpcAppToService);
this.ServiceParent.HostIpcAppToService.Open();
return true;
}
Я читал, что служба автоматически запустит службы, размещенные в App.Config
файле, на самом деле в MyExeName.exe.config
файле. Я продолжал просматривать код и увидел, что он почти идентичен, поэтому я заменил http://
на net.pipe://
.
Sadly, old code, new code, in between code, all nothing. I keep receiving the same error.
I use the following to connect to the service from my desktop application.
public static Boolean ConnectToService()
{
try
{
var callback = new IpcCallbackAppToService();
var context = new InstanceContext(callback);
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyIpcAppToService"));
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;
return true;
}
catch (Exception ex)
{
// Log the exception.
Errors.LogException(ex);
}
return false;
}
For whatever it is worth, here is:
Interface
[ServiceContract(SessionMode = SessionMode.Allowed, CallbackContract = typeof(IIpcCallbackAppToService))]
public interface IIpcAppToService
{
[OperationContract(IsOneWay = false)]
[FaultContractAttribute(typeof(IpcAppToServiceFault))]
UInt16 GetServiceId();
...
}
Service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class IpcAppToService : IIpcAppToService, IErrorHandler
{
public static IIpcCallbackAppToService Callback { get; set; } = null;
public void OpenCallback()
{
IpcAppToService.Callback = OperationContext.Current.GetCallbackChannel<IIpcCallbackAppToService>();
}
public void CloseCallback()
{
IpcAppToService.Callback = null;
}
public void SendMessage(string message)
{
//MessageBox.Show(message);
}
public UInt16 GetServiceId()
{
return Constants.My_Id_AppToService;
}
...
}
Inner Exception from my desktop WinForms Application
(Note, there were no further inner exceptions than this one.):
«The pipe endpoint ‘net.pipe://localhost/MyIpcAppToService’ could not be found on your local machine.»
Why do I keep seeing this error?
UPDATE AFTER 1ST ANSWER
The direction that I would like to take is opposite of the answer, yet the same, namely that the service starts with the App.config
and the client
uses C# code.
Sadly, I still get the same error.
Revised Server Side App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="BehaviorMyService" name="MyService.Communication.IpcAppToService">
<endpoint address="net.pipe://localhost/MyIpcAppToService"
binding="netNamedPipeBinding"
bindingConfiguration="EndpointBindingMyAppToService"
contract="MyIpc.IIpcAppToService"
/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorMyService">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="true"
/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netNamedPipeBinding>
<!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
<binding name="EndpointBindingMyAppToService"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxBufferSize="65536"
maxConnections="10"
maxReceivedMessageSize="2147483647"
>
<security mode="None">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://localhost:8733"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
<appSettings>
<add key="countoffiles" value="7"/>
<add key="logfilelocation" value="abc.txt"/>
</appSettings>
</configuration>
Пересмотренный код C # на стороне клиента:
var callback = new IpcCallbackAppToService();
InstanceContext context = new InstanceContext(callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.Security.Mode = NetNamedPipeSecurityMode.None;
EndpointAddress endpointAddress = new EndpointAddress("net.pipe://localhost/MyIpcAppToService");
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, binding, endpointAddress);
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;
Служба не выдает исключений, которые я могу обнаружить, поскольку EventViewer чист, только сообщение об успешном завершении OnStart (). Я знаю, что система обрабатывает App.config
файл, так как ранее, когда у меня были ошибки, Windows Event Viewer
продолжал жаловаться, но не больше.
Вот некоторые документы Microsoft, которые я использовал:
Я пробовал IO Ninja, но указав \.pipeMyIpcToService
for File Stream
, Pipe Listener
и Pipe Monitor
, но там ничего не отображается, даже когда я пытаюсь подключиться с помощью моего настольного приложения WinForms, которое затем выдает исключение no pipe listener found.
В чем может быть проблема?
Комментарии:
1. Итак, существует ли InnerException?
2. @stuartd В данном случае был, но там говорилось то же самое: «Не удалось найти конечную точку канала ‘net.pipe://localhost/MyIpcAppToService’ на вашем локальном компьютере».
3. Щелчок правой кнопкой мыши по моему клиентскому приложению и выбор Add> Добавить ссылку на службу и вставка «net.pipe://localhost /MyIpcAppToService / mex» выдает то же сообщение, подразумевающее проблему на стороне сервера.
Ответ №1:
<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
Убедитесь, что адрес службы имеет ту же форму (транспортный протокол), что и тип привязки.
- TCP (net.tcp://localhost:8000/myservice) NetTcpBinding
- IPC(net.pipe://localhost/mypipe) Привязка NetNamedPipeBinding
-
Http / Https(http://localhost:8000/myservice )
Wshttpbinding,Wsdualhttpbinding,basichttpbinding -
WebSocket(ws://localhost:3434) Nethttpbinding
-
MSMQ(net.msmq://localhost/ private/myservice) Привязка NETMSMQ
предполагается, что мы должны использовать привязку NetNamedPipeBinding для адреса службы. Пожалуйста, обратитесь к моему примеру.
Обновлено
У меня есть служба wcf, использующая привязку NetNamedPipeBinding, размещенную в IIS, хотелось бы, чтобы она была вам полезна.
Сервер (приложение-служба wcf)
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Web.config (на стороне сервера)
<system.serviceModel>
<services>
<service behaviorConfiguration="BehaviorMyService" name="WcfService1.Service1">
<endpoint address="MyIpcAppToService"
binding="netNamedPipeBinding"
bindingConfiguration="EndpointBindingMyAppToService"
contract="WcfService1.IService1"
/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorMyService">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netNamedPipeBinding>
<binding name="EndpointBindingMyAppToService"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxConnections="10"
maxReceivedMessageSize="2147483647"
>
<security mode="None">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>
Включите новую функцию WCF.
Сайт IIS (включить net.pipe)
Клиент (консольное приложение)
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
var result = client.GetData(34);
Console.WriteLine(result);
Клиентское приложение.config (автоматически генерируется)
Я использую http-адрес (метаданные службы ПОЛУЧАЮТ адресhttp://localhost:8733/Service1.svc?wsdl ) для создания конфигурации.
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IService1">
<security mode="None" />
</binding>
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address="net.pipe://mynetpipe/Service1.svc/MyIpcAppToService"
binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IService1"
contract="ServiceReference1.IService1" name="NetNamedPipeBinding_IService1" />
</client>
</system.serviceModel>
Не стесняйтесь, дайте мне знать, если я могу чем-нибудь помочь.
Комментарии:
1. Я реализовал то, что вы предложили, см. Мой обновленный вопрос, только наоборот, а именно App.config для серверной части и C # для клиентской части. Я все еще получаю ту же ошибку. IO Ninja, не то чтобы я был экспертом в этом инструменте, не помогает в отладке.
2. Я закомментировал службу из App.config на сервере и добавил в код C #. Я сохранил код C # на клиенте и получил ту же ошибку. Что интересно, так это вторая часть «прослушивания конечной точки нет», которая «могла бы принять сообщение». Это может означать проблему на стороне клиента, а на стороне сервера все в порядке. Я проведу расследование.
3. На мой взгляд, что-то не так с публикацией службы через NetPIPE. Я обновил свой ответ, изменив свой пример, желаю, чтобы он был вам полезен.
4. Я заставил службу работать без дополнительных скриншотов, хотя мне пришлось использовать C # на сервере Windows, а не на
App.config
. Я не смог заставить службу работать с файлом конфигурации. Теперь, когда я пишу, возможно, мне нужно было создать файл .SVC, а не только 4 файла C #. Это работает. Спасибо! Дополнительная информация носит информативный характер.