5.WebSocket API(Xamarin.Forms)

★ご注意

以下は、Microsoft Visual Studio Community 2019 の Xamarin.Forms を使用して、Android・iOS・UWP向けクライアントアプリを開発する場合を想定した WebSocket API のご説明とサンプルプログラムです。

 

光CTIスマートコネクトサービスは、WebSocket APIを提供します。

※Windows 7SP1 では動作しません。WebSocket API をご利用の際は、 Windows 8、8.1、10 をご使用ください。
(Windows 7SP1 は OSレベルの WebSocketに非対応のため、
ご利用いただけません。)

 

【サンプルプログラムの利用方法】

  1. サーバーにするパソコンに「光CTIスマートコネクトサービス」をインストールします。
  2. Microsoft Visual Studio Community 2019 で Xamarin.Formsの新規プロジェクトを作成します。
  3. NuGetパッケージマネージャーで「System.Net.Websockets」を全プロジェクトにインストールします。
  4. NuGetパッケージマネージャーで Xamarin.Forms 他を最新の状態に更新しておきます。
  5. UWPプロジェクトの場合は、機能の「インターネット(クライアント)」と「プライベートネットワーク(クライアントとサーバー)」にチェックを付けます。
  6. 以下の【クライアントプログラム(Xamarin.Forms用)のサンプルソース① MainPage.xaml】を参考にプログラムを作成します。
  7. 以下の【クライアントプログラム(Xamarin.Forms用)のサンプルソース② MainPage.xaml.cs】を参考にプログラムを作成します。
  8. 作成したクライアントプログラム(Xamarin.Forms用)をビルド後、実機(Android・iOS・UWP)上で実行します。

 

【使用するポート】

  • 55963ポート(サービス側のパソコンでオープンが必要です。)

 

【クライアントプログラム(Xamarin.Forms用)のサンプルソース① MainPage.xaml】

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="ClientWebSocketSample.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Xamarin.Forms WebSocketサンプル" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
        <Button Text="サービスへ接続" x:Name="サービスへ接続" Clicked="サービスへ接続_Clicked" />
        <Button Text="サービスから切断" x:Name="サービスから切断" Clicked="サービスから切断_Clicked" />
    </StackLayout>

</ContentPage>

 

【クライアントプログラム(Xamarin.Forms用)のサンプルソース② MainPage.xaml.cs】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Net.WebSockets;
using System.Threading;

namespace ClientWebSocketSample
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        private ClientWebSocket _ws = null;

        public MainPage()
        {
            InitializeComponent();
        }

        //光CTIスマートコネクトサービスへ接続
        private async void サービスへ接続_Clicked(object sender, EventArgs e)
        {
            try
            {
                int _cnt = 1;

                _ws = new ClientWebSocket();

                //接続先エンドポイントを指定(光CTIスマートコネクトサービス稼働中PCのIPアドレスで指定する)
                Uri serverUri = new Uri("ws://192.168.24.36:55963/CTI_SmartConnectService/WebSocket/");

                //キープアライブタイマーの間隔を5分に設定
                _ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(5 * 60 * 1000);

                //サービスに接続
                await _ws.ConnectAsync(serverUri, CancellationToken.None);
                while (_ws.State == WebSocketState.Open)
                {
                    if (_cnt == 1)   //1回だけ実行
                    {
                        _cnt++;

                        //サービスへメッセージを送信
                        string sendmsg = "Regist('クライアント名')";
                        ArraySegment<byte> bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendmsg));
                        await _ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);
                    }

                    //サービスからメッセージを受信
                    ArraySegment<byte> bytesReceived = new ArraySegment<byte>(new byte[1024]);
                    WebSocketReceiveResult result = await _ws.ReceiveAsync(bytesReceived, CancellationToken.None);
                    string recvmsg = Encoding.UTF8.GetString(bytesReceived.Array, 0, result.Count);
                    if (string.IsNullOrEmpty(recvmsg) == false)
                    {
                        await DisplayAlert("サービスからの通知", recvmsg, "OK");
                    }
                }
            }
            catch (Exception ex)
            {
                await DisplayAlert("エラー", ex.Message, "OK");
            }
        }

        //光CTIスマートコネクトサービスから切断
        private async void サービスから切断_Clicked(object sender, EventArgs e)
        {
            try
            {
                if (_ws != null && _ws.State == WebSocketState.Open)
                {
                    //サービスへメッセージを送信
                    string sendmsg = "UnRegist('クライアント名')";
                    ArraySegment<byte> bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendmsg));
                    await _ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);

                    await DisplayAlert("確認", "光CTIスマートコネクトサービスから切断しました。", "OK");
                }
            }
            catch (Exception ex)
            {
                await DisplayAlert("エラー", ex.Message, "OK");
            }
        }
    }
}

 

 

【実行画面サンプル】

 

 

【光CTIスマートコネクトサービスWebSocket API仕様】

アドレス ws://(サービス実行中のパソコンのIPアドレス):55963/CTI_SmartConnectService/WebSocket/
バインディング
customBinding(netHttpBinding からの派生)
データ名称 Send メッセージ
接続中クライアントリストへ登録する Regist(‘name’)
  • name = クライアント名を設定します。
接続中クライアントリストから登録解除する UnRegist(‘name’)
  • name = クライアント名を設定します。
キープアライブ(タイムアウトを防ぐため、クライアントから5分間隔で呼び出す)

※調査の結果、本メッセージを送信しなくても接続がキープされているようです。

KeepAlive(‘name’)
WCFのタイムアウトを防ぐため、クライアントから定期的にキープアライブをコールします。(10分以内に1回コールする必要があります。)

  • name = クライアント名を設定します。
データ名称 CallBack メッセージ
サービスからの通知 {
“title”:”タイトル”,
“msg”:”メッセージ”,
“tyakusin_nichiji”:”着信日時”,
“from”:”相手TEL”,
“to”:”着信TEL”,
“kokyaku_id”:”顧客ID”,
“kokyaku_name”:”顧客名(会社名)”,
“tantou_name”:”担当者名”,
“syubetsu”:”回線種別”
}

※JSON形式

サービスから着信メッセージ、クライアント生存確認、処理完了通知がコールバックされます。

  • title  = メッセージタイトルがセットされています。
  • msg = メッセージ本文がセットされています。
  • tyakusin_nichiji = 着信日時がセットされています。
  • from = 相手TELがセットされています。
  • to = 着信TELがセットされています。
  • kokyaku_id = 顧客IDがセットされています。
  • kokyaku_name = 顧客名(会社名)がセットされています。
  • tantou_name = 担当者名がセットされています。
  • syubetsu = 回線種別がセットされています。