Windows Runtime アプリでの Wi-Fi to Cellular handover
Windows 10 Mobile で、「Wi-Fi接続が制限されている時にモバイルデータ通信を使う」という設定が追加されていました。
Android でも Lollipop 以降の Nexus ではデフォルトで同等機能が有効(ベンダーのカスタマイズによって挙動が違ったりする最悪な状況ですが)だったりしますが、API Level 21 で追加されたNetwork 関連クラスを使用することで、通信に使われるネットワークインタフェースをアプリからバインドすることができます。
Windows 8.1 までの Windows Runtime 既存APIで、Android と同じようにインタフェースのバインドができるのか調べてみました。
BindServiceNameAsync(String, NetworkAdapter) メソッドを使えば NetworkAdapter を直接バインドできます。
ConnectAsync(HostName, String, SocketProtectionLevel, NetworkAdapter) メソッドを使えば NetworkAdapter をバインドした上で接続してくれそうです。
このクラスには NetworkAdapter をバインドする API は用意されていないように見えます。。
つまり、HTTP通信をWi-Fiのインタフェースにバインドしたい場合、HttpClient ではなく StreamSocket で実装する必要があるようです。
Android でも Lollipop 以降の Nexus ではデフォルトで同等機能が有効(ベンダーのカスタマイズによって挙動が違ったりする最悪な状況ですが)だったりしますが、API Level 21 で追加されたNetwork 関連クラスを使用することで、通信に使われるネットワークインタフェースをアプリからバインドすることができます。
Windows 8.1 までの Windows Runtime 既存APIで、Android と同じようにインタフェースのバインドができるのか調べてみました。
UDP
Windows Runtime API では、UDP 通信に Windows.Networking.Sockets.DatagramSocket を使用します。BindServiceNameAsync(String, NetworkAdapter) メソッドを使えば NetworkAdapter を直接バインドできます。
var filter = new ConnectionProfileFilter
{
IsConnected = true,
IsWwanConnectionProfile = false,
IsWlanConnectionProfile = true
};
var profiles = await NetworkInformation.FindConnectionProfilesAsync(filter);
foreach (var profile in profiles)
{
var socket = new DatagramSocket();
await socket.BindServiceNameAsync("", profile.NetworkAdapter);
...
//
というわけで、こちらはデフォルトのインタフェースが Cellular に変更されても問題なし。(バインドした通りに動いてくれるなら。)TCP
生のTCP 通信には Windows.Networking.Sockets.StreamSocket を使用します。ConnectAsync(HostName, String, SocketProtectionLevel, NetworkAdapter) メソッドを使えば NetworkAdapter をバインドした上で接続してくれそうです。
var filter = new ConnectionProfileFilter
{
IsConnected = true,
IsWwanConnectionProfile = false,
IsWlanConnectionProfile = true
};
var profiles = await NetworkInformation.FindConnectionProfilesAsync(filter);
foreach (var profile in profiles)
{
var socket = new StreamSocket();
var host = new HostName("192.168.0.1");
await socket.ConnectAsync(host, "80", SocketProtectionLevel.PlainSocket, profile.NetworkAdapter);
...
//
生のTCPも問題なさそうです。HTTP
HTTP も TCP ですが、普通は StreamSocket ではなく Windows.Web.Http.HttpClient を使用します。このクラスには NetworkAdapter をバインドする API は用意されていないように見えます。。
つまり、HTTP通信をWi-Fiのインタフェースにバインドしたい場合、HttpClient ではなく StreamSocket で実装する必要があるようです。
コメント
コメントを投稿