使ってみよう! Live Framework

第5回 .NET Kit(2)

この記事を読むのに必要な時間:およそ 5 分

Mesh Objectにデバイスを関連付ける,つまりMesh ObjectのMappingコレクションにMappingを追加するコードは,次のようになります。コードではMesh内にあるMesh Objectのうち最初に見つかったLive Mesh フォルダ(Resource.Typeが"LiveMeshFolder")に対してすべてのデバイスを関連付けています。

' Live Mesh フォルダの取得
Dim mos = From mo In loe.Mesh.MeshObjects.Entries _
   Where mo.Resource.Type = "LiveMeshFolder" _
   Take 1
Dim meshObject = mos.SingleOrDefault

' すべてのデバイスを関連付け
For Each d In loe.Mesh.Devices.Entries
    Dim map = New Mapping ' Mapping オブジェクト作成
    map.Device = d ' デバイスの指定
    meshObject.Mappings.Add(map) ' Mapping コレクションに追加
Next

上記のコードでは,少なくともひとつのLive Meshフォルダが存在している必要があります。また,関連付けしようとしたデバイスが既に関連付いている場合,正しく動作しません。実際には次のようにチェックが必要です。

For Each d In loe.Mesh.Devices.Entries
    ' 既にデバイスが関連付けられているかチェック
    Dim id = d.Resource.Id
    If meshObject.Mappings.Entries.Any(Function(m) m.Device.Resource.Id = id) Then
        Continue For
    End If

    Dim map = New Mapping ' Mapping オブジェクト作成
    map.Device = d ' デバイスの指定
    meshObject.Mappings.Add(map) ' Mapping コレクションに追加
Next

上記コードではすべてのリソース(ここではDevice)にあるIdプロパティを用いてチェックを行っています。

Live Mesh Betaサービスを思い出してみてください。デバイスがWindows PCの場合,エクスプローラと統合しクライアントPC上の実フォルダとしてLive Meshフォルダが存在していました。こういったMesh Objectと対象デバイスのファイルパスとの対応関係を表すには,MappingのResource.DataFeedMappingsプロパティを使用します。ただし,現在のLive Framework CTPではエクスプローラ統合機能はありませんので,Live Meshフォルダを作成してもこのプロパティには値が格納されていません。

ChangeNotificationReceived

それでは変更通知を受け取ってみましょう。変更を知るだけであれば非常に簡単です。Mesh Objectや,Data Feedなどのコレクションを表すオブジェクトにはChangeNotificationReceivedというイベントがあり,これを利用します。

Mesh Object,Data Feed,Data Entryの変更を受け取るコードは以下のようになります。コードではMesh上で最初に見つかったLive Meshフォルダに対する変更を受信するようにしています。

' Live Mesh フォルダの取得
Dim mos = From mo In loe.Mesh.MeshObjects.Entries _
   Where mo.Resource.Type = "LiveMeshFolder" _
   Take 1
Dim meshObject = mos.SingleOrDefault

' Mesh Object に対する変更通知
AddHandler meshObject.ChangeNotificationReceived, AddressOf MeshObject_ChangeNotificationReceived

' Mesh Object 内の Data Feed コレクションに対する変更通知
AddHandler meshObject.DataFeeds.ChangeNotificationReceived, AddressOf DataFeeds_ChangeNotificationReceived

' Data Feed 内の Data Entry コレクションに対する変更通知
For Each df In meshObject.DataFeeds.Entries
    AddHandler df.DataEntries.LiveItemCollectionChanged, AddressOf DataEntries_LiveItemCollectionChanged
Next

Private Sub MeshObject_ChangeNotificationReceived(ByVal sender As Object, ByVal e As EventArgs)
    Console.WriteLine("MeshObject_ChangeNotificationReceived")
End Sub
Private Sub DataFeeds_ChangeNotificationReceived(ByVal sender As Object, ByVal e As EventArgs)
    Console.WriteLine("DataFeeds_ChangeNotificationReceived")
End Sub
Private Sub DataEntries_ChangeNotificationReceived(ByVal sender As Object, ByVal e As EventArgs)
    Console.WriteLine("DataEntries_ChangeNotificationReceived")
End Sub

変更を受信した場合,コンソールに呼び出されたメソッド名を表示しています。実際にアプリケーションを実行して,Live DesktopからLive Meshフォルダ内のファイルの追加・削除・変更,フォルダ自身の変更などの操作をして通知されるか確認してみてください。操作から通知されるまで多少の時間は要しますが,それほど時間はかからないと思います。この仕組みを利用してチャットアプリケーションにも使用できそうです。

現在のところ,ChangeNotificationReceivedイベントで受け取るsenderオブジェクトは変更のあったMesh Objectやコレクション自身,eオブジェクトはNothing(null)となっており,具体的な変更(追加や削除など)の内容はイベントおよびその引数からはわかりません。

同期と衝突

さて,第1回目にLive Mesh Betaサービスを紹介したときにも まったく触れていませんでしたが,データの同期には衝突(Conflict)が生じる可能性があります。たとえば,ネットワークがオフライン時にクライアント上のLOEに接続しデータを編集した場合,オンラインになった時点でLOEが自動で更新データを反映します。このとき,オフライン時に別のデバイスから対象データの更新があった場合,更新されたデータのバージョンがふたつ存在することになります。こうなると,どちらを選択するかはアプリケーションまたはユーザーが決定する必要があります。

Live Meshフォルダ内のファイルが衝突した場合は,図4のようにMesh Barに衝突している旨の表示と,どのバージョンのファイルを残すかユーザーが選択することができます。

図4 ファイルが衝突した場合

図4 ファイルが衝突した場合

衝突はData Entryに対して起こります。前回に既に紹介した方法でData Entryを参照している限りでは,衝突していてもしていなくても,あるひとつのバージョンのData Entryが参照できます。少し言い換えると衝突しているData Entryも問題なく参照でき,変更も可能です。

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp