バックグラウンドタスクでソケットをリッスンする – SocketActivityTrigger

SocketActivityTrigger

UWPのBackgroundTaskは、さまざまなトリガーによってプロセスの開始を可能にします。

その中でもSocketActivityTriggerというものを使うと、システムが受信したソケットに反応してUWPのバックグラウンドタスクを開始することができます。

2種類の方法

SocketActivityTriggerを利用したバックグラウンドソケット通信には2種類存在します。

  • フォアグランドでConnectしたソケットをバックグラウンドへ渡す
  • フォアグラウンドでリッスンしているリスナーをバックグラウンドへ渡す

前者の場合、かずきさんのブログ公式のサンプルに載っているのでそちらを参考にしてください。

 

今回のサンプルは後者の場合です。フォアグラウンドでソケットリッスンを開始し、バックグラウンドタスクへソケットリスナーを渡し、バックグラウンドでコネクションを確立します。

ソケットが閉じてもOSが再起動してもリッスンを再開します。

サンプル

サンプルはここに置いているので参考にしてください。

https://github.com/garicchi/uwp-background-socket

ポイント

SocketActivityTriggerにはポイントがいくつかあります。

まず普通にBackgroundTaskBuilderでタスクを生成しますが、TriggerにはSocketActivityTriggerを渡します。

その後、StreamSocketListenerでソケット待ち受けをしますが、バインドする前にEnableTransferOwnershipメソッドを呼んで、バックグラウンドにリスナーを渡す許可をしなければいけません。

ここでSocketActivityConnectedStandbyAction列挙体を入れる必要があります。公式サンプルではWakeになってますがDoNotWakeにしてください。(じゃないと動かない)

バインド完了したら以下の2文でソケットリスナーをバックグラウンドに渡します。

私のサンプルではバインド直後にいれていますが、OnSuspending時にやってもいいと思います。

バックグラウンドタスクではTriggerDetailのReasonプロパティを使用して、どのソケットイベントがきているかを判断します。

まず、ソケットリッスン状態でアクセプトできるソケットが来た場合、ConnectionAcceptedになります。

Acceptは自動で行われるのでここが呼び出された時点でアクセプトされています。

その後、StreamSocketListenerでアクセプトされたソケットを取得する必要がありますがイベントでしか取得できないので、イベントがちゃんと発火されるまで2秒ぐらいまちます。

コネクションを張れたら、このバックグラウンドタスクに再度受信したソケットの権限を渡します。

こうすることでアクセプトされたソケットに来る信号も、このタスクで取得できるようになります。

ソケットにデータが書き込まれたときはSocketActivityになります。

ここは普通にDataReaderでデータを1バイト読み取ります。

ソケットはsocketInformationのStreamSocketから取得します。

ソケットが閉じられたときは再度Listenをします。

ここが不思議なところなのですが、ソケットが閉じられたときだけじゃなく、OSが起動した時、SocketClosedが2回呼び出されます。

つまりSocketClosedが呼びされたタイミングでListenを開始すればOSが再起動してもListenを継続できます。

しかし2回呼び出されるのは厄介なので今リッスンしてるソケットの数で判断しています。

動作例

AndroidのアプリであるSimpleSocketTesterからソケットを送ってみています。

この手法は公式のサンプルにもないので少々難しいですね。質問は@garicchiにて受け付けています。




No Comments


You can leave the first : )



Leave a Reply

Your email address will not be published. Required fields are marked *