Walkthrough: Deploy Microsoft .NET or Silverlight WebSocket Clients to iOS or Android Using Xamarin
In this walkthrough, you will learn how to deploy an existing Microsoft .NET WebSocket web client as a Xamarin app for iOS and Android. This procedure demonstrates how you can build a Microsoft .NET WebSocket client using the Kaazing WebSocket Gateway Microsoft .NET WebSocket client library and then use Xamarin to deploy the client as an app on iOS or Android devices.
This topic walks you through the following subjects:
- What You Will Accomplish
- Before You Begin
- Install the Gateway and Xamarin 3
- Configure Xamarin
- Reusing UIs with Xamarin.Forms
- Run the Gateway
- Build the Xamarin Apps
- Run and Test the Xamarin App in iOS Simulator or Android Emulator
- WebSocket Event Handlers in Xamarin
What You Will Accomplish
At the end of this walkthrough, an Xamarin .NET WebSocket demo created using the Kaazing WebSocket Gateway Microsoft .NET and Silverlight WebSocket library runs as an app on iOS and Android, connects to the Gateway, and sends and receives Echo messages using an emulated WebSocket connection. Users can run the Xamarin app on any iOS or Android device.
This walkthrough uses the out of the box Xamarin WebSocket demo that is included with the Gateway as the example app, but the steps outlined in this walkthrough are the same for other Xamarin WebSocket client applications built with the Gateway.
Before You Begin
Before starting this walkthrough you need the following:
- Kaazing WebSocket Gateway. See Setting Up Kaazing WebSocket Gateway.
- Xamarin Platform 3.
- An Xamarin account. To create an Xamarin account, see https://store.xamarin.com/Login?from=%2faccount%2f.
- iOS SDK. The iOS SDK is required in order to use the iOS Simulator. For the iOS SDK, see https://developer.apple.com/xcode/. You can run the Xamarin iOS demo on iOS 5.1+, 6.0+, 7.0+, and 8.0+.
- Android SDK. The Android SDK is required in order to use the Android Emulator. For the Android SDK, see https://developer.android.com/sdk/index.html.
- Learn about supported browsers, operating systems, and platform versions in Release Notes.
Install the Gateway and Xamarin 3
The following steps link to resources to take you through the installation of the software required for deploying an Xamarin app. If you already have this software installed, you can simply note the locations of the installed software for later use.
- Install the Gateway as described in Setting Up Kaazing WebSocket Gateway.
- Download and install Xamarin 3 from http://xamarin.com/platform.
Configure Xamarin
The following steps configure Xamarin Studio for building the iOS and Android apps.
- Launch Xamarin Studio.
- Click the Xamarin Studio menu and click Account.
- Click Log In. Log in with your account information.
- Close the Account dialog.
- Add the Kaazing WebSocket Gateway demo.
- In Xamarin Studio, click Open.
- Navigate to the location of the Xamarin demos in your distribution of the Gateway: GATEWAY_HOME/demo/xamarin/src/gateway.
- Click the file named gateway.client.xamarin.demo.sln and click Open. Xamarin Studio loads the demos for Android and iOS. The following demos are loaded:
- KaazingGatewayXamarinDemo.Android
- KaazingGatewayXamarinDemo.Common
- KaazingGatewayXamarinDemo.iOS.Classic
- KaazingGatewayXamarinDemo.iOS.Unified
- KaazingGatewayXamarinDemo.Android and KaazingGatewayXamarinDemo.iOS.Classic both share KaazingGatewayXamarinDemo.Common. The UI is defined once using Xamarin.Forms in KaazingGatewayXamarinDemo.Common and is reused by the iOS and Android projects. Similarly, the code that handles user events in KaazingGatewayXamarinDemo.Common is reused by the iOS and Android projects. This method demonstrates how to develop an app using C# and deploy the same app to both iOS and Android.
- The Xamarin.Forms package is not available for the Unified API. As a result, KaazingGatewayXamarinDemo.iOS.Unified defines its own UI using a storyboard and has code for dealing with user events. KaazingGatewayXamarinDemo.iOS.Unified is not sharing or reusing the code from KaazingGatewayXamarinDemo.Common like KaazingGatewayXamarinDemo.Android and KaazingGatewayXamarinDemo.iOS.Classic are. For more information, see http://forums.xamarin.com/discussion/24616/xamarin-forms-and-ios-unified-api.
- The Kaazing WebSocket Gateway .NET client library, Kaazing.Gateway.dll, is picked up from GATEWAY_HOME/demo/xamarin/src/gateway/KaazingLibs automatically.
Reusing UIs with Xamarin.Forms
Xamarin.Forms is a cross-platform natively backed UI toolkit abstraction that allows developers to easily create user interfaces that can be shared across Android and iOS. The Kaazing WebSocket Gateway Xamarin demo uses Xamarin.Forms to implement the UI once and reuse it across multiple platforms and thus avoid duplication. With Xamarin.Forms, the UI is built using C# code instead of a storyboard for iOS and XAML for Android. The same C# code is then reused for iOS and Android platforms.
Xamarin.Forms is used to share the UI in KaazingGatewayXamarinDemo.Common with KaazingGatewayXamarinDemo.Android and KaazingGatewayXamarinDemo.iOS.Classic, but not with KaazingGatewayXamarinDemo.iOS.Unified.
Classic and Unified APIs
The Kaazing WebSocket Gateway Xamarin includes projects that showcase how to build iOS apps under Xamarin using both Classic and Unified APIs. Xamarin recommends using the Unified API, but Xamarin.Forms works well with Classic API only, at this time. Xamarin.Forms for the Unified API is still in pre-release stage and has issues.
While the project for KaazingGatewayXamarinDemo.iOS.Classic uses the Xamarin.Forms’ reusable UI that is shared with KaazingGatewayXamarinDemo.Android, the KaazingGatewayXamarinDemo.iOS.Unified project does not use Xamarin.Forms. Instead, the UI for KaazingGatewayXamarinDemo.iOS.Unified is defined in a storyboard just as it is done in Xcode for a regular iOS project and has its own event-handling code written in C#.
Run the Gateway
The following steps review the Echo service and start the Gateway.
Open the GATEWAY_HOME/conf/gateway-config.xml file in a text editor. Review the echo service to see the configuration of the connection to the Gateway. For example:
<service> <name>echo</name> <description>Simple echo service</description> <accept>ws://build-macmini.kaazing.test:${gateway.extras.port}/echo</accept> <type>echo</type> <realm-name>demo</realm-name> <!-- <authorization-constraint> <require-role>AUTHORIZED</require-role> </authorization-constraint> --> <cross-site-constraint> <allow-origin>http://build-macmini.kaazing.test:${gateway.extras.port}</allow-origin> </cross-site-constraint> </service>
Note: By default, the Gateway uses Property defaults for ws://build-macmini.kaazing.test:${gateway.extras.port}/echo and the actual URI is ws://localhost:8001/echo. The Android Emulator or device will not allow the use of localhost. For Android, change the value of the accept tag to the local IP address of the Gateway server.- Start the Gateway as described in Setting Up Kaazing WebSocket Gateway. Invoke the
gateway.start
command by navigating to the GATEWAY_HOME/bin directory where you installed the Gateway, and then enter the following to run thegateway.start
script:
./gateway.start (gateway.start.bat in Windows)
Build the Xamarin Apps
The following steps build the Xamarin apps for iOS and Android using the Xamarin project you created.
- For Android, right-click the Android demo named KaazingGatewayXamarinDemo.Android, and then click Build Project_Name, where Project_Name is the name of the project.
- For iOS, right-click either the iOS demo named KaazingGatewayXamarinDemo.iOS.Unified, KaazingGatewayXamarinDemo.Common, or KaazingGatewayXamarinDemo.iOS.Classic, and then click Build Project_Name.
Xamarin Studio informs you that the project is built. If you encounter Kaazing WebSocket Gateway .NET library errors, ensure that you have included the library in the Reference folder for the demo as described in Configure Xamarin.
Run and Test the Xamarin App in iOS Simulator or Android Emulator
The following steps run the Xamarin app and test the connection to the Gateway.
Note: The iOS SDK is required in order to use the iOS Emulator. For the iOS SDK, see https://developer.apple.com/xcode/. You can run the Xamarin iOS demo on iOS 5.1+, 6.0+, 7.0+, and 8.0+. The Android SDK is required in order to use the Android Emulator. For the Android SDK, see https://developer.android.com/sdk/index.html.Run the Xamarin App in the Android Emulator
For information on using the Android Emulator in Xamarin Studio, see the Xamarin article here: http://developer.xamarin.com/guides/android/getting_started/installation/configure_emulator/.
- Start the Android virtual device you will use for testing.
- Click the Android demo.
- In the top left of Xamarin Studio, click Debug in the dropdown menu.
- Click Select Device, then click Virtual Devices and select the Android Emulator virtual device. If the Android Emulator is not running, click Manage Devices and then start the emulator. Wait for the emulator to start before running the demo.
- For the demo, you need to run a virtual device with Android 4.4.2 API 19 or later. In you do not have a virtual device with this requirement (in the Android Virtual Device Manager, you will see the message No system images installed for this target), then you need to install Android 4.4.2 (API 19) using the Android SDK Manager (in the Android SDK Manager, click the Tools menu, and then click Android SDK Manager). Here is an example virtual device setup:
- Device: Nexus 5
- Target: Android 4.4.2 - API Level 19
- CPU/ABI: ARM (armeabi-v7a)
- Run the Android demo. In Xamarin Studio, click the Android demo, and then click the Play button. The virtual device displays the demo.
Run the Xamarin App in the iOS Simulator
For iOS, see the iOS Simulator guide here: https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/iOS_Simulator_Guide/Introduction/Introduction.html.
- Run the iOS demo.
- In Xamarin, click the iOS demo.
- In the top left of Xamarin Studio, right-click the iOS demo, click Run With, and then click an iOS Simulator (for example, iPhone 6 / iOS 8.1). The iOS Simulator opens and displays the demo.
Test the iOS or Android Demo
The following step test the Xamarin app on the iOS Simulator or Android Emulator.
- In the demo running in the iOS Simulator or Android Emulator, click Connect. The demo connects to the Gateway.
Note: The Android Emulator or device will not allow the use of localhost. For the Android, change the value of the accept tag in the configuration file of the Gateway to the local IP address of the Gateway server, and enter the IP address in the Location field of the app. - Click Send. The message is sent and the Echo message is received.
WebSocket Event Handlers in Xamarin
You can see the WebSocket event handlers in the file KaazingGatewayDemoController.cs in KaazingGatewayXamarinDemo.Common, shown below. The code demonstrates WebSocket open, close, and message events. In addition, the code demonstrates how to use a Login Handler and Challenge Handler to perform user authentication using the Gateway.
using System; using Xamarin.Forms; using System.Collections.Generic; using Kaazing.Security; using System.Threading.Tasks; using Kaazing.HTML5; using System.Threading; using System.Diagnostics; namespace KaazingGatewayXamarinDemo { public class KaazingGatewayDemoController { protected KaazingGatewayDemoPage _demoPage; bool _isConnected = false; string _username = null; string _password = null; AutoResetEvent _userInputCompleted; WebSocket _webSocket = null; public KaazingGatewayDemoController(KaazingGatewayDemoPage demoPage) { _demoPage = demoPage; _webSocket = new WebSocket(); BasicChallengeHandler basicHandler = ChallengeHandlers.Load<BasicChallengeHandler>(typeof(BasicChallengeHandler)); basicHandler.LoginHandler = new KaazingDemoLoginHandler(this); ChallengeHandlers.Default = basicHandler; _webSocket.OpenEvent += new OpenEventHandler(OpenHandler); _webSocket.CloseEvent += new CloseEventHandler(CloseHandler); _webSocket.MessageEvent += new MessageEventHandler(MessageHandler); _userInputCompleted = new AutoResetEvent(false); } public void SetUsernameAndPassword(string username, string password) { _username = username; _password = password; // Once the member variables are set, now unblock the other // thread so that it can create credentials using the username/password. _userInputCompleted.Set(); } public async void ConnectOrDisconnect(object sender, EventArgs eventArgs) { try { if (!_isConnected) { string uriInput = _demoPage.URI; _demoPage.Log("CONNECTING: " + uriInput); await Task.Factory.StartNew(() => { _webSocket.Connect(uriInput); }); } else { _demoPage.Log("CLOSING"); await Task.Factory.StartNew(() => { _webSocket.Close (); }); } } catch(Exception exc) { _demoPage.Log("CONNECTION FAILED: " + exc.Message); } } /// /// HTML5 Event Handlers /// private void OpenHandler(object sender, OpenEventArgs args) { // Enable User Interface for Connected application _demoPage.EnableUI(true); _isConnected = true; _demoPage.Log("CONNECTED"); } private void CloseHandler(object sender, CloseEventArgs args) { _demoPage.EnableUI(false); _isConnected = false; _demoPage.Log("DISCONNECTED"); } private void MessageHandler(object sender, MessageEventArgs args) { _demoPage.Log("RECIEVED MESSAGE: " + args.Data); } // async public void SendMessage(object sender, EventArgs eventArgs) { string messageInput = _demoPage.Message; await Task.Factory.StartNew(() => { _webSocket.Send (messageInput); }); _demoPage.Log("SEND: " + messageInput); } public void ClearLog(object sender, EventArgs eventArgs) { Device.BeginInvokeOnMainThread(() => { _demoPage.LogView = ""; }); } // public PasswordAuthentication AuthenticationHandler() { PasswordAuthentication credentials = null; try { _userInputCompleted.Reset(); Device.BeginInvokeOnMainThread(() => { _demoPage.Navigation.PushModalAsync(new KaazingDemoLoginPage(this)); }); _userInputCompleted.WaitOne(); credentials = new PasswordAuthentication(_username, _password.ToCharArray()); } catch(Exception ex) { _demoPage.Log(ex.Message); } return credentials; } } }