[Xamarin] iOS 與Android結合SignalR

[Xamarin] iOS 與Android結合SignalR

目前網路上有許多範例討論到以Signal R來實作聊天室,這一篇文章就來把iPhone還有Android都接上SignalR吧!

如果了解SignalR的概念,可以先參考下列這些文章:

SignalR 再次超越你對 Web 的想像 - 建立即時互動的 Web

http://blogs.msdn.com/b/msdntaiwan/archive/2013/09/09/signalr-reimagine-web-development.aspx

使用ASP.NET SignalR設計聊天室

http://blogs.uuu.com.tw/Articles/post/2014/02/26/%E4%BD%BF%E7%94%A8ASPNET-SignalR%E8%A8%AD%E8%A8%88%E8%81%8A%E5%A4%A9%E5%AE%A4.aspx

 

這篇文章範例原文出處是來自於國外Greg Shackles的文章,範例程式下載位置在下方

How To Use SignalR in iOS and Android Apps

http://visualstudiomagazine.com/articles/2013/11/01/how-to-use-signalr-in-ios-and-android-apps.aspx

我就以這個範例直接來實作。

 

接下來進入正題,這篇文章要分三個範例來看。分別如下:

1. Signal R Server端的程式。

2. Xamarin.Android專案。

3. Xamarin.iOS專案。

clip_image001

 

1. Signal R Server端的程式。

1.1 建立Hub。

在這個範例中,Hub裡面只建立了一個方法,Send,這個方法裡面帶了兩個參數,原作者讓他可以傳入目前使用者適用哪一種手機以及聊天訊息。

clip_image003

 

1.2 接著在Startup檔案中對應SignalR的路由。

clip_image004

 

1.3接著在我的範例中,我將這個Server端程式發佈到Windows Azure上。

比較需要注意的地方,在Windows Azure上,Web Socket的設定要開啟。

clip_image006

 

2. Xamarin.Android專案。

在Xamarin.Android專案中,首先會建立一個Client.cs的類別。這是一個跨平台的類別,可以同時被Xamarin.Android還有Xamarin.iOS參考。這個類別負責與後端的SignalR 伺服器端程式做連結。

(這個檔案可以同時提供給Android,iOS,Windows Phone,windows 8 一起使用,這就是Xamarin跨平台的魅力了!!)

2.1 Client.cs檔案的方法內容


namespace ChatClient.Shared
{
    public class Client
    {
        private readonly string _platform;
        private readonly HubConnection _connection;
        private readonly IHubProxy _proxy;
        //Handler當Device收到資訊時候的事件
        public event EventHandler OnMessageReceived;

        //建構子:當這個類別被呼叫的時候,回傳入使用者目前所使用的Device
        public Client(string platform)
        {
            //平台
            _platform = platform;
            //負責連接Server端的程式,這邊我是放在Windows Azure
            _connection = new HubConnection("http://benlusignalr2.azurewebsites.net/");
            //SignalR 上Hub名稱
            _proxy = _connection.CreateHubProxy("Chat");
        }

        //負責連線的方法
        public async Task Connect()
        {
            await _connection.Start();

            _proxy.On("messageReceived", (string platform, string message) =>
            {
                if (OnMessageReceived != null)
                    OnMessageReceived(this, string.Format("{0}: {1}", platform, message));
            });

            //呼叫Send方法,並且送出一個Connected字串
            Send("Connected");
        }

        //被呼叫的方法
        public Task Send(string message)
        {
            return _proxy.Invoke("Send", _platform, message);
        }
    }
}

 

 

2.2 Xamarin.Android的Layout畫面檔案內容

在畫面檔案中建立一個文字編輯標籤以及Listview來讓使用者可以輸入以及條列資訊。


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Input" />
  <ListView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Messages" />
</LinearLayout>

 

2.3 編輯Activity檔案,來實作與SignalR Server的資料溝通。


namespace ChatClient.Droid
{
    [Activity(Label = "Chat Client", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        protected override async void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            SetContentView(Resource.Layout.Main);

           

            var input = FindViewById(Resource.Id.Input);
            var messages = FindViewById(Resource.Id.Messages);

            var inputManager = (InputMethodManager)GetSystemService(InputMethodService);
            var adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, new List());

            messages.Adapter = adapter;

            //建立物件並且呼叫建構子傳入目前使用的手機
            var client = new Client("Android");
            //連接Web Socket
            await client.Connect();

            input.EditorAction +=
              delegate
              {
                  inputManager.HideSoftInputFromWindow(input.WindowToken, HideSoftInputFlags.None);

                  if (string.IsNullOrEmpty(input.Text))
                      return;
                  //呼叫client.Send方法送出文字標籤的資訊
                  client.Send(input.Text);

                  input.Text = "";
              };

            //OnMessageReceived的事件接收
            client.OnMessageReceived +=
              (sender, message) => RunOnUiThread(() =>
                adapter.Add(message));
        }
    }
}

 

2.4 編譯Android程式。

一進來Android程式,Android會去連結Windows Azure上面的SignalR Server site程式。連結成功就會丟出一個Android:Connected。

這時輸入一個Hello! Android!,馬上可以看到下方的Lisview資訊被更新了,但是這樣好像還是感受不到他有多酷!

clip_image008 clip_image010

 

在同一時間去iOS模擬器上的畫面也被更新了,這樣是不是就酷多了!

clip_image012

 

參考資訊:

How To Use SignalR in iOS and Android Apps

http://visualstudiomagazine.com/articles/2013/11/01/how-to-use-signalr-in-ios-and-android-apps.aspx