Real-time chat UWP application using Azure Mobile App and SignalR
https://msdnshared.blob.core.windows.net/media/2016/05/0640_NinjaAwardTinyGold.pngGold Award Winner
Introduction
ASP.NET SignalR is a library for ASP.NET developers that makes developing real-time web functionality easy. SignalR allows bi-directional communication between server and client. Servers can push content to connected clients instantly as it becomes available.
In this tutorial, I am gonna show you how you can create a real-time chat UWP application using Azure Mobile App and SignalR. You can easily implement cool features of Azure Mobile App like user authentication and push notifications along with SignalR bi-directional communication to create awesome real-time apps.
Create a new Azure Mobile App backend
Follow these steps to create a new Mobile App backend.
- Log into the Azure Portal.
- In the top left of the window, click the +NEW button > Web + Mobile > Mobile App, then provide a name for your Mobile App backend.
- In the Resource Group box, select an existing resource group. If you have no resource groups, enter the same name as your app. At this point, the default App Service plan is selected, which is in the Standard tier. The App Service plan settings determine the location, features, cost and compute resources associated with your app. You can either select another App Service plan or create a new one. For more about App Services plans and how to create a new plan in a different pricing tier and in your desired location, see Azure App Service plans in-depth overview
- Use the default App Service plan, select a different plan or create a new plan, then click Create. This creates the Mobile App backend. Later you will deploy your server project to this backend. Provisioning a Mobile App backend can take several minutes; the Settings blade for the Mobile App backend is displayed when complete. Before you can use the Mobile App backend, you must also define a connection a data store.
(For this tutorial we are not going to use the database but you must define a connection to one in order to create the .NET Backend successfully.)
Configure the server project
- Back in the Mobile App backend settings, click Quick start > your client platform.
- Under Create a table API, select C#:
- Click Download, extract the compressed project files to your local computer, open the solution in Visual Studio, build the project to restore the NuGet packages, then deploy the project to Azure. To learn how to deploy a .NET backend server project to Azure, see How to: Publish the server project in the .NET backend SDK topic.
You Mobile App backend is now ready to use with your client app.
(Taken from here)
Now, we are ready to install SignalR package to our Mobile App.
Right Click your Mobile App project and click Manage NuGet Packages… as shown below.
https://uwpstories.files.wordpress.com/2016/02/1.png?w=712
Select the Browse tab if it’s not already selected and search for SignalR and select Microsoft.AspNet.SignalR.Core package**.** Then click Install
**
**https://uwpstories.files.wordpress.com/2016/02/2.png?w=712
Click OK to the first popup and accept the second one.
It should now create a Scripts folder.
Ready to write some code?
Create a ChatMessage.cs class inside the DataObjects folder.
Add the following code.
public class ChatMessage
{
public string Username { get; set; }
public string Message { get; set; }
}
Create a new folder under your project’s root and name it whatever you want. I named mine Hubs.
Create a new class inside your folder named ChatHub.cs.
Add the following code.
public class ChatHub : Hub
{
public void Send(ChatMessage message)
{
Clients.All.broadcastMessage(message);
}
}
The SignalR Hubs API enables you to make remote procedure calls (RPCs) from a server to connected clients and from clients to the server. In server code, you define methods that can be called by clients, and you call methods that run on the client. In client code, you define methods that can be called from the server, and you call methods that run on the server. SignalR takes care of all of the client-to-server plumbing for you.
void Send(ChatMessage message) will be invoked by the clients
Server will broadcast this message to every connected client by Clients.All.broadcastMessage(message)
Simple right?
Last but not least, open the Startup.cs class which is located in your project’s root and add app.MapSignalR(); below ConfigureMobileApp(app);
This will map SignalR to the app builder pipeline.
And that’s it! Your mobile app service is ready.
Create your UWP Client Application
Let’s create our UWP Application.
Start by creating a new project by going to File->New->Project->Visual C#->Windows and select Blank App (Universal Windows) and name it whatever you want.
Then, right click your UWP project and click Manage NuGet Packages… like before.
Select the Browse tab if it’s not already selected and search for SignalR and select Microsoft.AspNet.SignalR.Client package this time**.** Then click Install
When it’s ready, create the same ChatMessage.cs class like before and place it wherever you want.
I am gonna use a simple data binding mechanic. If you need more info on what data binding is start here.
Create a class named ChatMessageViewModel.cs this will be used to represent our Chat Messages on our view.
public class ChatMessageViewModel { public ObservableCollection<ChatMessage> Messages { get; set; } = new ObservableCollection<ChatMessage>(); }
Then, open App.xaml.cs and declare the following public variables
public ChatMessageViewModel ChatVM { get; set; }; = new ChatMessageViewModel(); public HubConnection conn { get; set; } public IHubProxy proxy { get; set; }
Add the following code inside the App.xaml.cs
public App() { this.InitializeComponent(); this.Suspending += OnSuspending; SignalR(); } public void SignalR() { conn = new HubConnection("http://<;your-mobile-app>.azurewebsites.net"); proxy = conn.CreateHubProxy("ChatHub"); conn.Start(); proxy.On<ChatMessage>("broadcastMessage", OnMessage); } public void Broadcast(ChatMessage msg) { proxy.Invoke("Send", msg); } private async void OnMessage(ChatMessage msg) { await Windows.ApplicationModel.Core.CoreApplication.MainView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { ChatVM.Messages.Add(msg); }); }
This will create the connection to our mobile app service, connect to our ChatHub
and register to broadcastMessage event which means, when the server sends a broadcastMessage message to us, OnMessage handler will be invoked.The OnMessage handler adds the received message to our ObservableCollection, Messages, and the Broadcast method is used to send the message to our service by invoking the server-side Send method.
Our Logic is ready!
Now, the only thing left is creating our View. Let’s use the MainPage for that.
<Page x:Class="ChatApplication.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ChatApplication" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" > <RelativePanel> <TextBox x:Name="name" RelativePanel.AlignRightWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignTopWithPanel="True"></TextBox> <ListView x:Name="lv" ItemsSource="{Binding Messages}" RelativePanel.Above="rp" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" RelativePanel.Below="name"> <ListView.ItemTemplate> <DataTemplate x:DataType="local:ChatMessage"> <StackPanel Orientation="Horizontal"> <TextBlock> <Run Text="{x:Bind Username}"></Run> <Run Text=": "></Run> <Run Text="{x:Bind Message}"></Run> </TextBlock> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> <RelativePanel x:Name="rp" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True"> <TextBox x:Name="text" RelativePanel.AlignLeftWithPanel="True" RelativePanel.LeftOf="send" ></TextBox> <Button x:Name="send" RelativePanel.AlignRightWithPanel="True" Content="Send" Click="send_Click"></Button> </RelativePanel> </RelativePanel> </Page>
That’s my super simple View. I am using a TextBox for the username, a ListView for the messages, which uses the Messages ObservableCollection as it’s ItemSource, one more TextBox for the message we would like to send and a Button.
public MainPage() { this.InitializeComponent(); this.DataContext = (Application.Current as App).ChatVM; } private void send_Click(object sender, RoutedEventArgs e) { (Application.Current as App).Broadcast(new ChatMessage {Username = name.Text, Message = text.Text}); }
And that’s the MainPage code behind the view.
I am just setting the DataContext of the MainPage to our ChatMessageViewModel and invoking the Broadcast method when the user clicks the button.
And voila! That’s it!
https://uwpstories.files.wordpress.com/2016/02/capture.png?w=712
Of course, you can follow the same logic to improve it with features like who’s online right now or private messaging. Also, you can even use push notifications and user authentication offered by Azure Mobile Apps easily.
You can find the GitHub repo here.
Thanks for reading!
George