5

LAN を介して配置された複数のクライアント アプリによって制御されるサーバー側にある音楽サーバー アプリケーションを制御するためのクライアント/サーバーの作成に数週間取り組んできました。クライアント側でサーバーと通信し、音楽サーバーを操作するコマンドを送信し、コールバックを使用してクライアントに応答し、すべてのクライアント UI を適切に更新できるようにすることに成功しました。ただし、私の問題は、サーバーアプリからクライアントに送信する必要がある他のメッセージをブロードキャストする方法がわからないことです。コールバック メソッドを利用したいと思っていました。ただし、サーバー側からアクセスできませんでした。サーバーからクライアントへの通信を提供する別のコントラクトを変更または作成する必要がありますか? バインディングを変更する必要がありますか? 先に述べたように、私は本当にこれに数週間 (「数年」のように感じ始めています) 取り組んでおり、アプリケーションのこの最後の部分が機能することを望んでいます。誰かが私を正しい方向に導いてくれませんか?

クライアント側のサービス参照:

<?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>

クライアント側の AP 設定

<?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>

サーバー側 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>

サーバー側 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); });
      }
 }

サーバー側 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);
 }
 }

サーバー側 - 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);
     }
4

0 に答える 0