2010-05-15 13 views
5

Ich arbeite seit Wochen an der Erstellung eines Client/Servers zur Steuerung einer Musikserver-Anwendung auf der Serverseite, die von mehreren Client-Apps im LAN gesteuert wird. Es ist mir gelungen, die Client-Seite mit dem Server zu kommunizieren, Befehle zum Betreiben des Musik-Servers zu senden und durch die Verwendung von Rückrufen den Clients zu antworten, so dass alle Benutzeroberflächen des Clients entsprechend aktualisiert werden können. Mein Problem ist jedoch, dass ich nicht in der Lage bin herauszufinden, wie andere Nachrichten gesendet werden sollen, die von der Server-App an die Clients gesendet werden müssen. Ich hatte gehofft, die Rückrufmethode zu verwenden; Ich konnte jedoch nicht von der Serverseite darauf zugreifen. Muss ich einen anderen Vertrag ändern oder erstellen, der die Kommunikation vom Server zu den Clients ermöglicht? Muss die Bindung geändert werden? Wie ich bereits erwähnt habe, arbeite ich seit Wochen wirklich daran (was sich allmählich wie "Jahre" anfühlt) und hoffe, dass dieser letzte Teil der Anwendung funktioniert. Würde mich bitte jemand in die richtige Richtung lenken?Bidirektionale WCF-Client-Server-Kommunikation

Client Side SERVICE REFERENCE:

<?xml version="1.0" encoding="utf-8"?> 
<ServiceReference> 
<ProxyGenerationParameters 
    ServiceReferenceUri="http://localhost:8001/APService/mex" 
    Name="APGateway" 
    NotifyPropertyChange="True" 
    UseObservableCollection="False"> 
</ProxyGenerationParameters> 
<EndPoints> 
    <EndPoint 
     Address="net.tcp://localhost:8000/APService/service" 
     BindingConfiguration="TcpBinding" 
     Contract="APClient.APGateway.APUserService" 
     > 
    </EndPoint> 
    <EndPoint 
     Address="http://localhost:8001/APService/service" 
     BindingConfiguration="HttpBinding" 
     Contract="APClient.APGateway.APUserService" 
     > 
    </EndPoint> 
</EndPoints> 
</ServiceReference> 

Client Side AP CONFIG

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
<configSections> 
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > 
     <section name="APClient.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </sectionGroup> 
</configSections> 
<system.serviceModel> 
    <client> 
     <endpoint 
      address="net.tcp://localhost:8000/APService/service" 
      binding="netTcpBinding" 
      contract="APClient.APGateway.APUserService" 
      name="TcpBinding" /> 
     <endpoint 
      address="http://localhost:8001/APService/service" 
      binding="wsDualHttpBinding" 
      contract="APClient.APGateway.APUserService" 
      name="HttpBinding" /> 
    </client> 
</system.serviceModel> 
<applicationSettings> 
    <APClient.Properties.Settings> 
     <setting name="pathToDatabase" serializeAs="String"> 
      <value>C:\Users\Bill\Documents\APData\</value> 
     </setting> 
    </APClient.Properties.Settings> 
</applicationSettings> 

Server Side AP.CONFIG

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="MetadataBehavior"> 
      <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8001/APService/mex" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service behaviorConfiguration="MetadataBehavior" name="APService.APService"> 
     <endpoint address="service" binding="netTcpBinding" name="TcpBinding" 
      contract="APService.IAPServiceInventory" /> 
     <endpoint address="service" binding="wsDualHttpBinding" name="HttpBinding" 
     contract="APService.IAPServiceInventory" /> 
     <endpoint address="mex" binding="mexHttpBinding" name="MexBinding" 
      contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.tcp://localhost:8000/APService/" /> 
      <add baseAddress="http://localhost:8001/APService/" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    </system.serviceModel> 
</configuration> 

Server Side APSERVICE.CS

namespace APService 
{ 
    [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single,InstanceContextMode=InstanceContextMode.PerCall)] 
public class APService : IAPServiceInventory 
{ 
     private static List<IClientCallback> _callbackList = new List<IClientCallback>(); 
     private static int _beerInventory = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["InitialBeerInventory"]); 
     public APService() {} 
     public int SubscribeToServer(string guestName) 
     { 
      IClientCallback guest = OperationContext.Current.GetCallbackChannel<IClientCallback>(); 
      if(!_callbackList.Contains(guest)) { _callbackList.Add(guest); } 
      else { Console.WriteLine(guest + " is already logged onto the Server."); } 
      _callbackList.ForEach(delegate(IClientCallback callback) { callback.NotifyGuestJoinedParty(guestName); }); 
     } 
     public void UpdateClients(string guestName,string UpdateInfo) 
     { 
      _callbackList.ForEach(delegate(IClientCallback callback) { callback.NotifyUpdateClients(guestName,UpdateInfo); }); 
     } 
     public void SendRequestToServer(string guestName, string request) 
     { 
      _callbackList.ForEach(delegate(IClientCallback callback) { callback.NotifyRequestMadeToServer(guestName,request); }); 
      if(request == "Play") { APControl.Play(); } 
      else if(request == "Stop") { APControl.Stop(); } 
      else if(request == "Pause") { APControl.PlayPause(); } 
      else if(request == "Next Track") { APControl.NextTrack(); } 
      else if(request == "Previous Track") { APControl.PreviousTrack(); } 
      else if(request == "Mute") { APControl.Mute(); } 
      else if(request == "Volume Up") { APControl.VolumeUp(5); } 
      else if(request == "Volume Down") { APControl.VolumeDown(5); } 
     } 
     public void CancelServerSubscription(string guestName) 
     { 
      IClientCallback guest = OperationContext.Current.GetCallbackChannel<IClientCallback>(); 
      if(_callbackList.Contains(guest)) { _callbackList.Remove(guest); } 
      _callbackList.ForEach(delegate(IClientCallback callback) { callback.NotifyGuestLeftParty(guestName); }); 
     } 
} 

Server Side IAPSERVICE.CS

namespace APService 
{ 
    [ServiceContract(Name="APUserService",Namespace="http://AP.com/WCFClientServer/",SessionMode=SessionMode.Required, CallbackContract=typeof(IClientCallback))] 
public interface IAPServiceInventory 
{ 
     [OperationContract()] 
     int SubscribeToServer(string guestName); 
     [OperationContract(IsOneWay=true)] 
     void SendRequestToServer(string guestName,string request); 
     [OperationContract(IsOneWay=true)] 
     void UpdateClients(string guestName,string UpdateInfo); 
     [OperationContract(IsOneWay=true)] 
     void CancelServerSubscription(string guestName); 
} 
} 

Seite Server - IAPServiceCallback.cs

namespace APService 
{ 
    public interface IClientCallback 
    { 
      [OperationContract(IsOneWay=true)] 
      void NotifyGuestJoinedParty(string guestName); 
      [OperationContract(IsOneWay=true)] 
      void NotifyUpdateClients(string guestName,string UpdateInfo); 
      [OperationContract(IsOneWay=true)] 
      void NotifyRequestMadeToServer(string guestName,string request); 
      [OperationContract(IsOneWay=true)] 
      void NotifyGuestLeftParty(string guestName); 
    } 

Antwort

1

Ich denke, man this link den Mechanismus zu verstehen, folgen können.

NLV