Så här implementerar du en identifieringsproxy
I det här avsnittet beskrivs hur du implementerar en identifieringsproxy. Mer information om identifieringsfunktionen i Windows Communication Foundation (WCF) finns i Översikt över WCF-identifiering. En identifieringsproxy kan implementeras genom att skapa en klass som utökar den DiscoveryProxy abstrakta klassen. Det finns ett antal andra stödklasser som definierats och används i det här exemplet. OnResolveAsyncResult
, OnFindAsyncResult
och AsyncResult
. Dessa klasser implementerar IAsyncResult gränssnittet. Mer information finns IAsyncResult i System.IAsyncResult-gränssnittet.
Implementeringen av en identifieringsproxy är uppdelad i tre huvuddelar i det här avsnittet:
Definiera en klass som innehåller ett datalager och utökar den abstrakta DiscoveryProxy klassen.
Implementera hjälpklassen
AsyncResult
.Värd för identifieringsproxyn.
Skapa ett nytt konsolprogramprojekt
Starta Visual Studio 2012.
Skapa ett nytt konsolprogramsprojekt. Namnge projektet
DiscoveryProxy
och namnet på lösningenDiscoveryProxyExample
.Lägg till följande referenser till projektet
System.ServiceModel.dll
System.Servicemodel.Discovery.dll
Varning
Se till att du refererar till version 4.0 eller senare av dessa sammansättningar.
Implementera klassen ProxyDiscoveryService
Lägg till en ny kodfil i projektet och ge den namnet DiscoveryProxy.cs.
Lägg till följande
using
direktiv i DiscoveryProxy.cs.using System; using System.Collections.Generic; using System.ServiceModel; using System.ServiceModel.Discovery; using System.Xml;
DiscoveryProxyService
Härled från DiscoveryProxy.ServiceBehavior
Använd attributet för klassen enligt följande exempel.// Implement DiscoveryProxy by extending the DiscoveryProxy class and overriding the abstract methods [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] public class DiscoveryProxyService : DiscoveryProxy { }
DiscoveryProxy
I klassen definierar du en ordlista som ska innehålla de registrerade tjänsterna.// Repository to store EndpointDiscoveryMetadata. Dictionary<EndpointAddress, EndpointDiscoveryMetadata> onlineServices;
Definiera en konstruktor som initierar ordlistan.
public DiscoveryProxyService() { this.onlineServices = new Dictionary<EndpointAddress, EndpointDiscoveryMetadata>(); }
Definiera de metoder som används för att uppdatera identifieringsproxycache
AddOnlineservice
Implementera metoden för att lägga till tjänster i cacheminnet. Detta anropas varje gång proxyn tar emot ett meddelandemeddelande.void AddOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata) { lock (this.onlineServices) { this.onlineServices[endpointDiscoveryMetadata.Address] = endpointDiscoveryMetadata; } PrintDiscoveryMetadata(endpointDiscoveryMetadata, "Adding"); }
Implementera den
RemoveOnlineService
metod som används för att ta bort tjänster från cacheminnet.void RemoveOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata) { if (endpointDiscoveryMetadata != null) { lock (this.onlineServices) { this.onlineServices.Remove(endpointDiscoveryMetadata.Address); } PrintDiscoveryMetadata(endpointDiscoveryMetadata, "Removing"); } }
Implementera de
MatchFromOnlineService
metoder som försöker matcha en tjänst med en tjänst i ordlistan.void MatchFromOnlineService(FindRequestContext findRequestContext) { lock (this.onlineServices) { foreach (EndpointDiscoveryMetadata endpointDiscoveryMetadata in this.onlineServices.Values) { if (findRequestContext.Criteria.IsMatch(endpointDiscoveryMetadata)) { findRequestContext.AddMatchingEndpoint(endpointDiscoveryMetadata); } } } }
EndpointDiscoveryMetadata MatchFromOnlineService(ResolveCriteria criteria) { EndpointDiscoveryMetadata matchingEndpoint = null; lock (this.onlineServices) { foreach (EndpointDiscoveryMetadata endpointDiscoveryMetadata in this.onlineServices.Values) { if (criteria.Address == endpointDiscoveryMetadata.Address) { matchingEndpoint = endpointDiscoveryMetadata; } } } return matchingEndpoint; }
Implementera metoden
PrintDiscoveryMetadata
som ger användaren konsoltextutdata för vad identifieringsproxyn gör.void PrintDiscoveryMetadata(EndpointDiscoveryMetadata endpointDiscoveryMetadata, string verb) { Console.WriteLine("\n**** " + verb + " service of the following type from cache. "); foreach (XmlQualifiedName contractName in endpointDiscoveryMetadata.ContractTypeNames) { Console.WriteLine("** " + contractName.ToString()); break; } Console.WriteLine("**** Operation Completed"); }
Lägg till följande AsyncResult-klasser i DiscoveryProxyService. Dessa klasser används för att skilja mellan de olika asynkrona åtgärdsresultaten.
sealed class OnOnlineAnnouncementAsyncResult : AsyncResult { public OnOnlineAnnouncementAsyncResult(AsyncCallback callback, object state) : base(callback, state) { this.Complete(true); } public static void End(IAsyncResult result) { AsyncResult.End<OnOnlineAnnouncementAsyncResult>(result); } } sealed class OnOfflineAnnouncementAsyncResult : AsyncResult { public OnOfflineAnnouncementAsyncResult(AsyncCallback callback, object state) : base(callback, state) { this.Complete(true); } public static void End(IAsyncResult result) { AsyncResult.End<OnOfflineAnnouncementAsyncResult>(result); } } sealed class OnFindAsyncResult : AsyncResult { public OnFindAsyncResult(AsyncCallback callback, object state) : base(callback, state) { this.Complete(true); } public static void End(IAsyncResult result) { AsyncResult.End<OnFindAsyncResult>(result); } } sealed class OnResolveAsyncResult : AsyncResult { EndpointDiscoveryMetadata matchingEndpoint; public OnResolveAsyncResult(EndpointDiscoveryMetadata matchingEndpoint, AsyncCallback callback, object state) : base(callback, state) { this.matchingEndpoint = matchingEndpoint; this.Complete(true); } public static EndpointDiscoveryMetadata End(IAsyncResult result) { OnResolveAsyncResult thisPtr = AsyncResult.End<OnResolveAsyncResult>(result); return thisPtr.matchingEndpoint; } }
Definiera de metoder som implementerar identifieringsproxyfunktionen
Åsidosätt DiscoveryProxy.OnBeginOnlineAnnouncement metoden. Den här metoden anropas när identifieringsproxyn tar emot ett meddelande online.
// OnBeginOnlineAnnouncement method is called when a Hello message is received by the Proxy protected override IAsyncResult OnBeginOnlineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state) { this.AddOnlineService(endpointDiscoveryMetadata); return new OnOnlineAnnouncementAsyncResult(callback, state); }
Åsidosätt DiscoveryProxy.OnEndOnlineAnnouncement metoden. Den här metoden anropas när identifieringsproxyn slutför bearbetningen av ett meddelandemeddelande.
protected override void OnEndOnlineAnnouncement(IAsyncResult result) { OnOnlineAnnouncementAsyncResult.End(result); }
Åsidosätt DiscoveryProxy.OnBeginOfflineAnnouncement metoden. Den här metoden anropas med identifieringsproxyn som tar emot ett meddelande offline.
// OnBeginOfflineAnnouncement method is called when a Bye message is received by the Proxy protected override IAsyncResult OnBeginOfflineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state) { this.RemoveOnlineService(endpointDiscoveryMetadata); return new OnOfflineAnnouncementAsyncResult(callback, state); }
Åsidosätt DiscoveryProxy.OnEndOfflineAnnouncement metoden. Den här metoden anropas när identifieringsproxyn har slutfört bearbetningen av ett meddelande offline.
protected override void OnEndOfflineAnnouncement(IAsyncResult result) { OnOfflineAnnouncementAsyncResult.End(result); }
Åsidosätt DiscoveryProxy.OnBeginFind metoden. Den här metoden anropas när identifieringsproxyn tar emot en sökbegäran.
// OnBeginFind method is called when a Probe request message is received by the Proxy protected override IAsyncResult OnBeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state) { this.MatchFromOnlineService(findRequestContext); return new OnFindAsyncResult(callback, state); } protected override IAsyncResult OnBeginFind(FindRequest findRequest, AsyncCallback callback, object state) { Collection<EndpointDiscoveryMetadata> matchingEndpoints = MatchFromCache(findRequest.Criteria); return new OnFindAsyncResult( matchingEndpoints, callback, state); }
Åsidosätt DiscoveryProxy.OnEndFind metoden. Den här metoden anropas när identifieringsproxyn slutför bearbetningen av en sökbegäran.
protected override void OnEndFind(IAsyncResult result) { OnFindAsyncResult.End(result); }
Åsidosätt DiscoveryProxy.OnBeginResolve metoden. Den här metoden anropas när identifieringsproxyn tar emot ett matchningsmeddelande.
// OnBeginFind method is called when a Resolve request message is received by the Proxy protected override IAsyncResult OnBeginResolve(ResolveCriteria resolveCriteria, AsyncCallback callback, object state) { return new OnResolveAsyncResult(this.MatchFromOnlineService(resolveCriteria), callback, state); } protected override IAsyncResult OnBeginResolve(ResolveRequest resolveRequest, AsyncCallback callback, object state) { return new OnResolveAsyncResult( this.proxy.MatchFromOnlineService(resolveRequest.Criteria), callback, state); }
Åsidosätt DiscoveryProxy.OnEndResolve metoden. Den här metoden anropas när identifieringsproxyn slutför bearbetningen av ett matchningsmeddelande.
protected override EndpointDiscoveryMetadata OnEndResolve(IAsyncResult result) { return OnResolveAsyncResult.End(result); }
The OnBegin.. /OnEnd.. metoder tillhandahåller logiken för efterföljande identifieringsåtgärder. Metoderna och OnEndFind implementerar till exempel OnBeginFind söklogik för identifieringsproxy. När identifieringsproxyn tar emot ett avsökningsmeddelande körs dessa metoder för att skicka ett svar tillbaka till klienten. Du kan ändra söklogik som du vill, till exempel kan du införliva anpassad omfångsmatchning med algoritmer eller programspecifik XML-metadataparsing som en del av sökåtgärden.
Implementera klassen AsyncResult
Definiera den abstrakta basklassen AsyncResult som används för att härleda de olika asynkrona resultatklasserna.
Skapa en ny kodfil med namnet AsyncResult.cs.
Lägg till följande
using
direktiv i AsyncResult.cs.using System; using System.Threading;
Lägg till följande AsyncResult-klass.
abstract class AsyncResult : IAsyncResult { AsyncCallback callback; bool completedSynchronously; bool endCalled; Exception exception; bool isCompleted; ManualResetEvent manualResetEvent; object state; object thisLock; protected AsyncResult(AsyncCallback callback, object state) { this.callback = callback; this.state = state; this.thisLock = new object(); } public object AsyncState { get { return state; } } public WaitHandle AsyncWaitHandle { get { if (manualResetEvent != null) { return manualResetEvent; } lock (ThisLock) { manualResetEvent ??= new ManualResetEvent(isCompleted); } return manualResetEvent; } } public bool CompletedSynchronously { get { return completedSynchronously; } } public bool IsCompleted { get { return isCompleted; } } object ThisLock { get { return this.thisLock; } } protected static TAsyncResult End<TAsyncResult>(IAsyncResult result) where TAsyncResult : AsyncResult { if (result == null) { throw new ArgumentNullException("result"); } TAsyncResult asyncResult = result as TAsyncResult; if (asyncResult == null) { throw new ArgumentException("Invalid async result.", "result"); } if (asyncResult.endCalled) { throw new InvalidOperationException("Async object already ended."); } asyncResult.endCalled = true; if (!asyncResult.isCompleted) { asyncResult.AsyncWaitHandle.WaitOne(); } if (asyncResult.manualResetEvent != null) { asyncResult.manualResetEvent.Close(); } if (asyncResult.exception != null) { throw asyncResult.exception; } return asyncResult; } protected void Complete(bool completedSynchronously) { if (isCompleted) { throw new InvalidOperationException("This async result is already completed."); } this.completedSynchronously = completedSynchronously; if (completedSynchronously) { this.isCompleted = true; } else { lock (ThisLock) { this.isCompleted = true; if (this.manualResetEvent != null) { this.manualResetEvent.Set(); } } } if (callback != null) { callback(this); } } protected void Complete(bool completedSynchronously, Exception exception) { this.exception = exception; Complete(completedSynchronously); } }
Värd för DiscoveryProxy
Öppna filen Program.cs i projektet DiscoveryProxyExample.
Lägg till följande
using
direktiv.using System; using System.ServiceModel; using System.ServiceModel.Discovery;
Lägg till följande kod i
Main()
metoden. Detta skapar en instans avDiscoveryProxy
klassen.Uri probeEndpointAddress = new Uri("net.tcp://localhost:8001/Probe"); Uri announcementEndpointAddress = new Uri("net.tcp://localhost:9021/Announcement"); // Host the DiscoveryProxy service ServiceHost proxyServiceHost = new ServiceHost(new DiscoveryProxyService());
Lägg sedan till följande kod för att lägga till en identifieringsslutpunkt och en slutpunkt för meddelanden.
try { // Add DiscoveryEndpoint to receive Probe and Resolve messages DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(new NetTcpBinding(), new EndpointAddress(probeEndpointAddress)); discoveryEndpoint.IsSystemEndpoint = false; // Add AnnouncementEndpoint to receive Hello and Bye announcement messages AnnouncementEndpoint announcementEndpoint = new AnnouncementEndpoint(new NetTcpBinding(), new EndpointAddress(announcementEndpointAddress)); proxyServiceHost.AddServiceEndpoint(discoveryEndpoint); proxyServiceHost.AddServiceEndpoint(announcementEndpoint); proxyServiceHost.Open(); Console.WriteLine("Proxy Service started."); Console.WriteLine(); Console.WriteLine("Press <ENTER> to terminate the service."); Console.WriteLine(); Console.ReadLine(); proxyServiceHost.Close(); } catch (CommunicationException e) { Console.WriteLine(e.Message); } catch (TimeoutException e) { Console.WriteLine(e.Message); } if (proxyServiceHost.State != CommunicationState.Closed) { Console.WriteLine("Aborting the service..."); proxyServiceHost.Abort(); }
Du har slutfört implementeringen av identifieringsproxyn. Fortsätt till Så här: Implementera en identifieringsbar tjänst som registreras med identifieringsproxyn.
Exempel
Det här är den fullständiga listan över den kod som används i det här avsnittet.
// DiscoveryProxy.cs
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Discovery;
using System.Xml;
namespace Microsoft.Samples.Discovery
{
// Implement DiscoveryProxy by extending the DiscoveryProxy class and overriding the abstract methods
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class DiscoveryProxyService : DiscoveryProxy
{
// Repository to store EndpointDiscoveryMetadata. A database or a flat file could also be used instead.
Dictionary<EndpointAddress, EndpointDiscoveryMetadata> onlineServices;
public DiscoveryProxyService()
{
this.onlineServices = new Dictionary<EndpointAddress, EndpointDiscoveryMetadata>();
}
// OnBeginOnlineAnnouncement method is called when a Hello message is received by the Proxy
protected override IAsyncResult OnBeginOnlineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state)
{
this.AddOnlineService(endpointDiscoveryMetadata);
return new OnOnlineAnnouncementAsyncResult(callback, state);
}
protected override void OnEndOnlineAnnouncement(IAsyncResult result)
{
OnOnlineAnnouncementAsyncResult.End(result);
}
// OnBeginOfflineAnnouncement method is called when a Bye message is received by the Proxy
protected override IAsyncResult OnBeginOfflineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state)
{
this.RemoveOnlineService(endpointDiscoveryMetadata);
return new OnOfflineAnnouncementAsyncResult(callback, state);
}
protected override void OnEndOfflineAnnouncement(IAsyncResult result)
{
OnOfflineAnnouncementAsyncResult.End(result);
}
// OnBeginFind method is called when a Probe request message is received by the Proxy
protected override IAsyncResult OnBeginFind(FindRequestContext findRequestContext, AsyncCallback callback, object state)
{
this.MatchFromOnlineService(findRequestContext);
return new OnFindAsyncResult(callback, state);
}
protected override void OnEndFind(IAsyncResult result)
{
OnFindAsyncResult.End(result);
}
// OnBeginFind method is called when a Resolve request message is received by the Proxy
protected override IAsyncResult OnBeginResolve(ResolveCriteria resolveCriteria, AsyncCallback callback, object state)
{
return new OnResolveAsyncResult(this.MatchFromOnlineService(resolveCriteria), callback, state);
}
protected override EndpointDiscoveryMetadata OnEndResolve(IAsyncResult result)
{
return OnResolveAsyncResult.End(result);
}
// The following are helper methods required by the Proxy implementation
void AddOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata)
{
lock (this.onlineServices)
{
this.onlineServices[endpointDiscoveryMetadata.Address] = endpointDiscoveryMetadata;
}
PrintDiscoveryMetadata(endpointDiscoveryMetadata, "Adding");
}
void RemoveOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata)
{
if (endpointDiscoveryMetadata != null)
{
lock (this.onlineServices)
{
this.onlineServices.Remove(endpointDiscoveryMetadata.Address);
}
PrintDiscoveryMetadata(endpointDiscoveryMetadata, "Removing");
}
}
void MatchFromOnlineService(FindRequestContext findRequestContext)
{
lock (this.onlineServices)
{
foreach (EndpointDiscoveryMetadata endpointDiscoveryMetadata in this.onlineServices.Values)
{
if (findRequestContext.Criteria.IsMatch(endpointDiscoveryMetadata))
{
findRequestContext.AddMatchingEndpoint(endpointDiscoveryMetadata);
}
}
}
}
EndpointDiscoveryMetadata MatchFromOnlineService(ResolveCriteria criteria)
{
EndpointDiscoveryMetadata matchingEndpoint = null;
lock (this.onlineServices)
{
foreach (EndpointDiscoveryMetadata endpointDiscoveryMetadata in this.onlineServices.Values)
{
if (criteria.Address == endpointDiscoveryMetadata.Address)
{
matchingEndpoint = endpointDiscoveryMetadata;
}
}
}
return matchingEndpoint;
}
void PrintDiscoveryMetadata(EndpointDiscoveryMetadata endpointDiscoveryMetadata, string verb)
{
Console.WriteLine("\n**** " + verb + " service of the following type from cache. ");
foreach (XmlQualifiedName contractName in endpointDiscoveryMetadata.ContractTypeNames)
{
Console.WriteLine("** " + contractName.ToString());
break;
}
Console.WriteLine("**** Operation Completed");
}
sealed class OnOnlineAnnouncementAsyncResult : AsyncResult
{
public OnOnlineAnnouncementAsyncResult(AsyncCallback callback, object state)
: base(callback, state)
{
this.Complete(true);
}
public static void End(IAsyncResult result)
{
AsyncResult.End<OnOnlineAnnouncementAsyncResult>(result);
}
}
sealed class OnOfflineAnnouncementAsyncResult : AsyncResult
{
public OnOfflineAnnouncementAsyncResult(AsyncCallback callback, object state)
: base(callback, state)
{
this.Complete(true);
}
public static void End(IAsyncResult result)
{
AsyncResult.End<OnOfflineAnnouncementAsyncResult>(result);
}
}
sealed class OnFindAsyncResult : AsyncResult
{
public OnFindAsyncResult(AsyncCallback callback, object state)
: base(callback, state)
{
this.Complete(true);
}
public static void End(IAsyncResult result)
{
AsyncResult.End<OnFindAsyncResult>(result);
}
}
sealed class OnResolveAsyncResult : AsyncResult
{
EndpointDiscoveryMetadata matchingEndpoint;
public OnResolveAsyncResult(EndpointDiscoveryMetadata matchingEndpoint, AsyncCallback callback, object state)
: base(callback, state)
{
this.matchingEndpoint = matchingEndpoint;
this.Complete(true);
}
public static EndpointDiscoveryMetadata End(IAsyncResult result)
{
OnResolveAsyncResult thisPtr = AsyncResult.End<OnResolveAsyncResult>(result);
return thisPtr.matchingEndpoint;
}
}
}
}
// AsyncResult.cs
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
using System;
using System.Threading;
namespace Microsoft.Samples.Discovery
{
abstract class AsyncResult : IAsyncResult
{
AsyncCallback callback;
bool completedSynchronously;
bool endCalled;
Exception exception;
bool isCompleted;
ManualResetEvent manualResetEvent;
object state;
object thisLock;
protected AsyncResult(AsyncCallback callback, object state)
{
this.callback = callback;
this.state = state;
this.thisLock = new object();
}
public object AsyncState
{
get
{
return state;
}
}
public WaitHandle AsyncWaitHandle
{
get
{
if (manualResetEvent != null)
{
return manualResetEvent;
}
lock (ThisLock)
{
manualResetEvent ??= new ManualResetEvent(isCompleted);
}
return manualResetEvent;
}
}
public bool CompletedSynchronously
{
get
{
return completedSynchronously;
}
}
public bool IsCompleted
{
get
{
return isCompleted;
}
}
object ThisLock
{
get
{
return this.thisLock;
}
}
protected static TAsyncResult End<TAsyncResult>(IAsyncResult result)
where TAsyncResult : AsyncResult
{
if (result == null)
{
throw new ArgumentNullException("result");
}
TAsyncResult asyncResult = result as TAsyncResult;
if (asyncResult == null)
{
throw new ArgumentException("Invalid async result.", "result");
}
if (asyncResult.endCalled)
{
throw new InvalidOperationException("Async object already ended.");
}
asyncResult.endCalled = true;
if (!asyncResult.isCompleted)
{
asyncResult.AsyncWaitHandle.WaitOne();
}
if (asyncResult.manualResetEvent != null)
{
asyncResult.manualResetEvent.Close();
}
if (asyncResult.exception != null)
{
throw asyncResult.exception;
}
return asyncResult;
}
protected void Complete(bool completedSynchronously)
{
if (isCompleted)
{
throw new InvalidOperationException("This async result is already completed.");
}
this.completedSynchronously = completedSynchronously;
if (completedSynchronously)
{
this.isCompleted = true;
}
else
{
lock (ThisLock)
{
this.isCompleted = true;
if (this.manualResetEvent != null)
{
this.manualResetEvent.Set();
}
}
}
if (callback != null)
{
callback(this);
}
}
protected void Complete(bool completedSynchronously, Exception exception)
{
this.exception = exception;
Complete(completedSynchronously);
}
}
}
// program.cs
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
using System;
using System.ServiceModel;
using System.ServiceModel.Discovery;
namespace Microsoft.Samples.Discovery
{
class Program
{
public static void Main()
{
Uri probeEndpointAddress = new Uri("net.tcp://localhost:8001/Probe");
Uri announcementEndpointAddress = new Uri("net.tcp://localhost:9021/Announcement");
// Host the DiscoveryProxy service
ServiceHost proxyServiceHost = new ServiceHost(new DiscoveryProxyService());
try
{
// Add DiscoveryEndpoint to receive Probe and Resolve messages
DiscoveryEndpoint discoveryEndpoint = new DiscoveryEndpoint(new NetTcpBinding(), new EndpointAddress(probeEndpointAddress));
discoveryEndpoint.IsSystemEndpoint = false;
// Add AnnouncementEndpoint to receive Hello and Bye announcement messages
AnnouncementEndpoint announcementEndpoint = new AnnouncementEndpoint(new NetTcpBinding(), new EndpointAddress(announcementEndpointAddress));
proxyServiceHost.AddServiceEndpoint(discoveryEndpoint);
proxyServiceHost.AddServiceEndpoint(announcementEndpoint);
proxyServiceHost.Open();
Console.WriteLine("Proxy Service started.");
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate the service.");
Console.WriteLine();
Console.ReadLine();
proxyServiceHost.Close();
}
catch (CommunicationException e)
{
Console.WriteLine(e.Message);
}
catch (TimeoutException e)
{
Console.WriteLine(e.Message);
}
if (proxyServiceHost.State != CommunicationState.Closed)
{
Console.WriteLine("Aborting the service...");
proxyServiceHost.Abort();
}
}
}
}