前もって決定する必要があるのは、リスト全体をインクリメント (重い) するか、更新された項目だけを各クライアントにプッシュするかです。以下のコードはリスト全体をプッシュするためのものですが、更新されたオブジェクトをプッシュするためだけにこれを簡単に変更できます (推奨)。
アプリの開始時に、クライアント B は を呼び出しRegister_client
、次にを呼び出す必要がありGetList
ます。その後、リストがインクリメントされると、コールバックを介して通知されます (クライアントはこのインターフェイスを実装する必要があります)
。呼び出しGetList
には、二重チャネルと が必要SessionMode.Required
です。
サーバーは次のことを実装する必要があります。
[ServiceContract(SessionMode = SessionMode.Required
CallbackContract = typeof(IMyCallback))]
public interface IMyServer {
[OperationContract]
void Register_client();
[OperationContract(IsOneWay = true)]
void IncrementList();
[OperationContract]
ListObject[] GetList();
}
[DataContract]
public class ListObject {
[DataMember]...
}
クライアントは次のことを暗示する必要があります。
public interface IMyCallback {
[OperationContract(IsOneWay = true)]
void PushList(ListObject[] list);
}
クライアントを登録するには、リストが次のようにインクリメントされたときに使用するストア クライアント コールバック インターフェイスが必要です。
public override void Register_client() {
// Store callback interfaces for all connected clients:
IMyCallback callback = OperationContext.Current.GetCallbackChannel<IGatewayServerCallback>();
if (clients.Contains(callback) == false)
clients.Add(callback);
Trace.WriteLine(string.Format("Client connection established ({0})", clients.Count));
}
どこ:
private List<IMyCallback> clients = new List<IMyCallback>();
の実装はIncrementList
、新しいリスト (または、リストに追加された新しいオブジェクトのみ) をクライアントにプッシュするコールバックを実行する必要があります。次のようなものです。
for (int i = 0; i < clients.Count; i++) {
if (((ICommunicationObject)clients[i]).State == CommunicationState.Opened) {
try {
clients[i].PushList(list);
}
catch (Exception e) {
clients.RemoveAt(i--);
Trace.WriteLine(e);
Trace.WriteLine(string.Format("Removing client {0} (exception).", i + 1));
}
}
コールバックの実装 (クライアント側) は次のようになります。
public class MyCallback : IMyCallback {
public void PushList(ListObject[] list) {
// Were client side - update list code here...
}
おそらく、このコールバックの実装には、リスト データを保持する何らかのオブジェクトへの参照が必要です。おそらく、これはコンストラクターに渡されます (表示されていません)。
プロキシ オブジェクトをインスタンス化するときは、次のようなコールバックのインスタンスをプロキシ コンストラクタに渡す必要があります。
MyServerClient client_proxy = new MyServerClient(new InstanceContext(my_callback, binding_str)