Szukam minimalnego przykładu potoków nazwanych WCF (oczekuję dwóch minimalnych aplikacji, serwera i klienta, które mogą komunikować się za pośrednictwem nazwanego potoku).
Firma Microsoft ma genialny artykuł samouczek wprowadzający, który opisuje WCF za pośrednictwem protokołu HTTP, i szukam czegoś podobnego na temat WCF i nazwanych potoków.
Znalazłem kilka postów w Internecie, ale są one trochę „zaawansowane”. Potrzebuję czegoś minimalnego, tylko obowiązkowej funkcjonalności, abym mógł dodać swój kod i uruchomić aplikację.
Jak to zmienić, aby użyć nazwanego potoku?
<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator" name="WSHttpBinding_ICalculator">
<identity>
<userPrincipalName value="OlegPc\Oleg" />
</identity>
</endpoint>
Jak to zmienić, aby użyć nazwanego potoku?
// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");
// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Step 4 of the hosting procedure: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
Jak wygenerować klienta, aby używał nazwanego potoku?
c#
wcf
named-pipes
Oleg Vazhnev
źródło
źródło
Odpowiedzi:
Właśnie znalazłem ten doskonały mały tutorial .uszkodzony link ( wersja w pamięci podręcznej )Postępowałem również zgodnie z tutorialem Microsoftu, który jest fajny, ale potrzebowałem też tylko rur.
Jak widać, nie potrzebujesz plików konfiguracyjnych i tych wszystkich bałaganu.
Nawiasem mówiąc, używa zarówno protokołu HTTP, jak i potoków. Po prostu usuń wszystkie linie kodu związane z HTTP, a otrzymasz przykład czystego potoku.
źródło
Spróbuj tego.
Oto część serwisowa.
[ServiceContract] public interface IService { [OperationContract] void HelloWorld(); } public class Service : IService { public void HelloWorld() { //Hello World } }
Oto serwer proxy
public class ServiceProxy : ClientBase<IService> { public ServiceProxy() : base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IService)), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyAppNameThatNobodyElseWillUse/helloservice"))) { } public void InvokeHelloWorld() { Channel.HelloWorld(); } }
A oto część dotycząca hostingu usług.
var serviceHost = new ServiceHost (typeof(Service), new Uri[] { new Uri("net.pipe://localhost/MyAppNameThatNobodyElseWillUse") }); serviceHost.AddServiceEndpoint(typeof(IService), new NetNamedPipeBinding(), "helloservice"); serviceHost.Open(); Console.WriteLine("Service started. Available in following endpoints"); foreach (var serviceEndpoint in serviceHost.Description.Endpoints) { Console.WriteLine(serviceEndpoint.ListenUri.AbsoluteUri); }
źródło
/helloservice
na końcu adresu punktu końcowego w proxy.Sprawdź mój bardzo uproszczony przykład Echo : jest przeznaczony do korzystania z podstawowej komunikacji HTTP, ale można go łatwo zmodyfikować, aby używał nazwanych potoków, edytując pliki app.config dla klienta i serwera. Wprowadź następujące zmiany:
Edytuj plik app.config serwera , usuwając lub komentując wpis http baseAddress i dodając nowy wpis baseAddress dla nazwanego potoku (o nazwie net.pipe ). Ponadto, jeśli nie zamierzasz używać HTTP jako protokołu komunikacyjnego, upewnij się, że serviceMetadata i serviceDebug są wykomentowane lub usunięte:
<configuration> <system.serviceModel> <services> <service name="com.aschneider.examples.wcf.services.EchoService"> <host> <baseAddresses> <add baseAddress="net.pipe://localhost/EchoService"/> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors></serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
Edytuj plik app.config klienta, tak aby element basicHttpBinding został wykomentowany lub usunięty oraz dodano wpis netNamedPipeBinding . Będziesz także musiał zmienić wpis punktu końcowego, aby użyć potoku:
<configuration> <system.serviceModel> <bindings> <netNamedPipeBinding> <binding name="NetNamedPipeBinding_IEchoService"/> </netNamedPipeBinding> </bindings> <client> <endpoint address = "net.pipe://localhost/EchoService" binding = "netNamedPipeBinding" bindingConfiguration = "NetNamedPipeBinding_IEchoService" contract = "EchoServiceReference.IEchoService" name = "NetNamedPipeBinding_IEchoService"/> </client> </system.serviceModel> </configuration>
Powyższy przykład będzie działał tylko z nazwanymi potokami, ale nic nie powstrzymuje Cię przed użyciem wielu protokołów do uruchomienia usługi. AFAIK, powinieneś być w stanie sprawić, by serwer uruchamiał usługę przy użyciu zarówno nazwanych potoków, jak i protokołu HTTP (a także innych protokołów).
Ponadto powiązanie w pliku app.config klienta jest znacznie uproszczone. Istnieje wiele różnych parametrów, które można dostosować, poza zwykłym określeniem adresu baseAddress ...
źródło
Stworzyłem ten prosty przykład na podstawie różnych wyników wyszukiwania w Internecie.
public static ServiceHost CreateServiceHost(Type serviceInterface, Type implementation) { //Create base address string baseAddress = "net.pipe://localhost/MyService"; ServiceHost serviceHost = new ServiceHost(implementation, new Uri(baseAddress)); //Net named pipe NetNamedPipeBinding binding = new NetNamedPipeBinding { MaxReceivedMessageSize = 2147483647 }; serviceHost.AddServiceEndpoint(serviceInterface, binding, baseAddress); //MEX - Meta data exchange ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); serviceHost.Description.Behaviors.Add(behavior); serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), baseAddress + "/mex/"); return serviceHost; }
Korzystając z powyższego URI, mogę dodać odniesienie w moim kliencie do usługi internetowej.
źródło
Uważam, że ta witryna jest naprawdę pomocna, a przykładowy projekt działa bez żadnych zmian: https://dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html
Nie zapomnij włączyć obsługi potoku nazwanego w funkcjach systemu Windows. W tym artykule znajdują się dobre zrzuty ekranu przedstawiające ten efekt w pierwszej odpowiedzi: potok nazwany WCF w usłudze Windows przy użyciu aplikacji.
Projekt, do którego odwołuje się zaakceptowane rozwiązanie, nie działa tak, jak jest na moim komputerze. Wypróbowałem kilka poprawek w pliku app.config, ale nadal otrzymuję następujący wyjątek:
źródło