UWP:MessageWebSocketのプログラム

MessageWebSocketを使ったWebSocket通信のサンプルプログラム。

インスタンス化と破棄

クラスメンバにインスタンスを保持しておく

MessageWebSocket messageWebSocket = new MessageWebSocket();
messageWebSocket.Dispose();

接続

DataWriterは送信時に使用するので、インスタンスを保持しておいてもいい。下記のwss://echo.websocket.orgはパブリックに公開されたWebSocketサーバーで接続すると、送信したメッセージがEchoバックされる簡易サーバーのURLである。

try {
    string surl = "wss://echo.websocket.org";
    await messageWebSocket.ConnectAsync( new Uri( surl ) );
    DataWriter messageWriter = new DataWriter( messageWebSocket.OutputStream );
} catch (Exception ex) {
    Windows.Web.WebErrorStatus webErrorStatus =
        WebSocketError.GetStatus( ex.GetBaseException().HResult );
}

受信処理

注意点として、MessageWebSocketは、上記のConnectAsync()を実行するまえにreceiveとcloseのデリゲートの指定を済ませておく必要がある。あとから指定しても動作しない。

messageWebSocket.Control.MessageType = SocketMessageType.Utf8;
messageWebSocket.MessageReceived += async (MessageWebSocket sender,
    MessageWebSocketMessageReceivedEventArgs args) => {
        int stat = 0;
        string message = "";
        uint bufsize = 512;
        try {
            IInputStream st = args.GetDataStream();
            DataReader re = new DataReader( st );
            re.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;

            while (true) {
                await re.LoadAsync( bufsize );
                if( re.UnconsumedBufferLength > 0) {
                    message += re.ReadString( re.UnconsumedBufferLength );
                    continue;
                }
                break;
            }
        } catch (Exception ex) {
            Windows.Web.WebErrorStatus webErrorStatus =
                WebSocketError.GetStatus( ex.GetBaseException().HResult );
        }
    };

クローズ処理

接続が解除されたときにコールバックされる。

messageWebSocket.Closed += (IWebSocket sender, WebSocketClosedEventArgs args) => {
    Debug.WriteLine( "WebSocket_Closed; Code: " + args.Code + ", Reason: \"" + args.Reason + "\"" );
};

送信処理

int stat = 0;
string strMessage = "hello";
try {
    messageWriter.WriteString( strMessage );
    await messageWriter.StoreAsync();
} catch (Exception ex) {
    Debug.WriteLine( "send exception:" + ex.Message );
    stat = -1;
}

その他(ローカルIPアドレス取得)

string strAddress = "";
var profile = NetworkInformation.GetInternetConnectionProfile();
if (profile != null && profile.NetworkAdapter != null) {
    foreach (var info in NetworkInformation.GetHostNames()) {
        if (info.Type == HostNameType.Ipv4 ) {
            if( info.CanonicalName.IndexOf(filter) == 0) {
                return info.CanonicalName;
            }
        }
    }
}

以下の場合、Windows SDKのバージョンが新しくないと動作しない。(Not Implimentationの例外がスロー)

NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in adapters) {

    // ネットワーク接続状態が UP のアダプタのみ表示 
    if (adapter.OperationalStatus == OperationalStatus.Up) {
        Debug.WriteLine( adapter.Name );
        Debug.WriteLine( adapter.Description );
        IPInterfaceProperties ip_prop = adapter.GetIPProperties();
        // 普通のIPアドレス取得(ブロードキャストなどは除く)
        UnicastIPAddressInformationCollection addrs = ip_prop.UnicastAddresses;
        foreach (UnicastIPAddressInformation addr in addrs) {

            // IPv4 : addr.Address.AddressFamily = Net.Sockets.AddressFamily.InterNetwork 
            // IPv6 : addr.Address.AddressFamily = Net.Sockets.AddressFamily.InterNetwork6 
            if (addr.Address.AddressFamily == AddressFamily.InterNetwork) {
                string ipv4 = addr.Address.ToString();

                Debug.WriteLine( ipv4 );

                if (ipv4.IndexOf( filter ) == 0) {
                    strAddress = ipv4;
                    return strAddress;
                }
            }
        }
    }
}