(5)サービスプロジェクト側にcrossdomain.xmlを置く
サービスプロジェクト側にcrossdomain.xmlを置きます。crossdomain.xmlは、自サイトから配信しているアプリケーション(Silverlightを含む)以外のアプリケーションからのサービスの呼び出しを許可するものです。
Visual Studioを2つ起動するとASP.NET開発サーバーが異なるポートを生成するため、異なるサイトであると認識し、エラーになります。動作確認の際に必要ですが、IISで配信するように変更するとサイトが固定されるため必要なくなります。

|
図4:Silverlightアプリケーションからのクロスドメインアクセスを許可する(クリックで拡大) |
(6)エンドポイントの宣言とレシーブ時に実行するコールバックを作成
クライアント側でサービス参照を更新してから、エンドポイントの宣言を作成し、レシーブ時に実行するコールバックを作成し、既存のGetStateの呼び出しをコメントアウトします。また、SetStateの呼び出しのみコメントアウトを外します。usingも2つ追加します。
[リスト 11]コールバックを持つサービスの呼び出し
01 | <!--//--><![CDATA[// ><!-- |
03 | using System.ServiceModel; |
04 | using System.ServiceModel.Channels; |
06 | public partial class MainPage : UserControl |
09 | static PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding(PollingDuplexMode.MultipleMessagesPerPoll); |
10 | DeskTopStateService.DeskTopStateServiceClient proxy = new DeskTopStateService.DeskTopStateServiceClient(binding, address); |
13 | InitializeComponent(); |
14 | //DeskTopStateService.DeskTopStateServiceClient proxy = new DeskTopStateService.DeskTopStateServiceClient(); |
16 | proxy.SetStateAsync("666", DeskTopStateService.DeskTopStateType.DayOff); |
17 | //proxy.GetStateCompleted += new EventHandler<DeskTopStateService.GetStateCompletedEventArgs>(proxy_GetStateCompleted); |
18 | //proxy.GetStateAsync(); |
19 | proxy.GetStateReceived += new EventHandler<DeskTopStateService.GetStateReceivedEventArgs>(proxy_GetStateReceived); |
21 | void proxy_GetStateReceived(object sender, DeskTopStateService.GetStateReceivedEventArgs e) |
26 | foreach (DeskTopStateService.DeskTopStateSet state in e.state) |
28 | result += state.ID + "/" + state.State + Environment.NewLine; |
31 | this.label1.Content = "在席状況一覧:" + Environment.NewLine + result; |
(7)エンドポイントのアドレスをコピーする
エンドポイントのアドレスは、Visual StudioのソリューションエクスプローラーでDeskTopStateService.svcを右クリックし、[ブラウザで表示]を選択して、Internet Explorerのアドレスバーからコピーしてください。

|
図5:ポート番号のコピー(クリックで拡大) |
(8)動作確認
F5キーを押して、動作を確かめてください。XMLファイルに保存されている「ユーザーID/在席状態」のセットの一覧が表示されればサービスの双方向化が完了です。

|
図6:結果の確認(クリックで拡大) |
全員への通知と開発サーバーからIISへの変更についてはソースコードを参照ください。
まとめ
第3~4回目では、WCF+Silverlightでの実装を解説してきました。
今回の実装方法では、クライアント側に多くのプログラムが自動生成され、作成したサーバー側プログラム(サービス)はわずか100行程度でした。このように、双方向通信に限らずプロトタイピングに適しているのがMicrosoft系の技術の特長です。
WCF+Silverlightの場合、エンドポイントのインタラクティビティの継続時間を2時間、サーバーポーリングタイムアウトの時間を5分に設定できたのは、コネクションが張りっ放しになるAjax+Cometと異なり、クライアントのコンテキストをサーバーが保持していて、各社員の在席状態の変更により、サーバーからメッセージ交換を開始するための通信を開始できる仕組みだったからということが重要です。
第5回は、必要に応じてサーバー、クライアント双方からコネクションを開始するWCF+Silverlightと異なり、サーバー - クライアント間の通信を張りっ放しにするHTML5+WebSocketsを解説します。