Calling server-side device methods from the client-hosted device UI

Calling server-side device methods from the client-hosted device UI

VS Project:

Connexion 14.5+ includes a framework to communicate directly with your server-side device from the associated device user-interface. This is often useful if you need to query for server-side state, perform a database lookup or connection availability, or run a specific method on the server.

In order to utilize these service calls, the following steps are required:

  1. Create an interface which defines all the methods implemented by the server-side device which the client UI will call

  2. Implement this interface in your server-side device

  3. Create a proxy variable in your device viewmodal class and use this to invoke the remote calls

In this example, we're going to add a diagnostics button to a device UI which will call our server-side device and display the resulting text.

First, create the interface:

public interface IDiagnostics { Task<string> GetDiagnosticsAsync(); }

Next, implement the interface in your device:

using System; using System.Threading; using Connexion.Core; using System.Threading.Tasks; namespace ProxySample1 { [DevicePlugin("ProxySample1", "Example of device proxying", DeviceDefinitionFlags.None, typeof(object), typeof(object), typeof(ProxySample1Factory))] public class ProxySample1 : BaseDevice<ProxySample1Configuration>, IDiagnostics { public override void Start() { } public override void Stop() { } public override async Task ProcessMessageAsync(IMessageContext context, CancellationToken token) { } public async Task<string> GetDiagnosticsAsync() { return Task.FromResult(Environment.MachineName); } } }

Now, create a proxy variable in your viewmodel. Note that we recommend you perform proxy calls on a different thread so that you do not block the UI thread.

using Connexion.Core; using System.Threading.Tasks; using System.Windows.Input; namespace ProxySample1 { public class ProxySample1UIViewModel : ViewModelBase { private ProxySample1Configuration m_Config; private IDeviceUIParams m_DeviceUIParams; private IDiagnostics m_Proxy; public ProxySample1UIViewModel(ProxySample1Configuration config, IDeviceUIParams deviceUIParams) { m_Config = config; m_DeviceUIParams = deviceUIParams; m_Proxy = deviceUIParams.GetServerDeviceProxy<IDiagnostics>(); // <-- creation of the proxy } public ProxySample1Configuration Configuration { get { return m_Config; } } private RelayCommand m_GetDiagnosticsCommand; public ICommand GetDiagnosticsCommand { get { return m_GetDiagnosticsCommand ?? (m_GetDiagnosticsCommand = new RelayCommand(async p => await GetDiagnostics())); } } private async Task GetDiagnostics() { try { DiagnosticResult = await m_Proxy.GetDiagnosticsAsync(); // <-- Calling the server } catch(exception ex) { DiagnosticResult = ex.Message; } } private string m_DiagnosticResult = "Click to run the diagnostics"; public string DiagnosticResult { get { return m_DiagnosticResult; } set { if(m_DiagnosticResult != value) { m_DiagnosticResult = value; RaisePropertyChanged(); } } } } }

Now we'll create the button and text box on the UI:

<UserControl x:Class="ProxySample1.ProxySample1UI" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Padding="6"> <Border Margin="10"> <StackPanel> <Button Command="{Binding GetDiagnosticsCommand}" Content="Get Diagnostics" /> <TextBox Text="{Binding DiagnosticResult, Mode=OneWay}" IsReadOnly="True" Margin="0,10,0,0" MinHeight="200" VerticalContentAlignment="Top"/> </StackPanel> </Border> </UserControl>

When clicking the button, we now get the following result: