Friday, 1 July 2016

Xamarin and Signal R - Chat Cross Platform

Using SignalR v2.x

2 parts:
Part 1: Create the core project, an MVC project, as a website in IIS.
Part 2: Xamarin and SignalR - Chat Cross Platform.


Part 2: Xamarin and SignalR

Common Issue:
Example:
SignalR - version of the client that isn't compatible with the server. Client version 1.4, server version undefined.

Error message: You are using a version of the client that isn't compatible  with the server.

This can be resolved easily by installing the same version from NuGet.


Sample - using SignalR Group.  - Chat.cshtml:
//https://code.msdn.microsoft.com/Getting-Started-with-c366b2f3
@{
    ViewBag.Title = "Chat";
}
<h2>Chat</h2>
<div class="container">
        <div id="typingstatus"></div>   
    <input type="text" id="message" />
    <input type="button" id="sendmessage" value="Send to everyone" />
        <input type="button" id="sendmessageToPeopleInRoom" value="Send to ppl in the same room" />
    <input type="hidden" id="displayname" />
        <input type="hidden" id="roomname" />
    <ul id="discussion"></ul>
</div>
@section scripts {
    <!--Script references. -->
    <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>
    <!--SignalR script to update the chat page and send messages.-->
    <script>
        $(function () {
            // Reference the auto-generated proxy for the hub.addNewMessageToPage
                var chat = $.connection.chatHub;



            // Create a function that the hub can call back to display messages.
                    //---------------Subscribe to when client is Typing and post a message to public
                chat.client.addNewMessageToPage = function (name, message) {

                    if (name == "typing") {
                        $('#typingstatus').html(message);
                    }else{
                // Add the message to the page.
                $('#discussion').append('<li><strong>' + htmlEncode(name)
                    + '</strong>: ' + htmlEncode(message) + '</li>');
                    }

                    //Clear the typing status
                    setTimeout("$('#typingstatus').empty();", 2000);
                };




            //---------------Subscribe to when client is Typing and post a message to private room
                chat.client.addChatMessage = function (name, message) {
                    $('#discussion').append('<li><strong>' + htmlEncode(name)
                    + '</strong>: ' + htmlEncode(message) + '</li>');
                };



            //--------------Subscribe to Client Join ROOM event
            chat.client.AddAnnouncement = function (roomName, message) {
                // Add the message to the page.
                $('#discussion').append('<li><strong><i>' + htmlEncode(message)
                                    + '</strong></i></li>');
            };


            //--------------General stuff
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            $('#roomname').val(prompt('Enter the room name:', ''));

            // Set initial focus to message input box.
            $('#message').focus();


            $username = $('#displayname').val();
            $roomname = $('#roomname').val();

          //-------------Start the connection.
            $.connection.hub.start().done(function () {

                chat.server.joinRoom($username, $roomname);
               
                $('#sendmessage').click(function () {
                    // Call the Send to all client method on the hub.
                        chat.server.sendToAllClient($('#displayname').val(), $('#message').val());

                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });


                $('#sendmessageToPeopleInRoom').click(function () {
                    // Call the Send to all client method on the hub.
                    chat.server.sendToSpecificRoom($('#displayname').val(), $('#message').val(), $('#roomname').val());

                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });
               
            });
        });
        // This optional function html-encodes messages for display in the page.
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>
}

--------------------------------------------------------

Example of HUB: ChatHub.cs


using System;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Threading.Tasks;

namespace SignalRChat
{
    public class ChatHub : Hub
    {
        #region general method. Either individual to everyone. or broadcast.

        //In chat.chtml, the callback method is actually the client method name instead of method name. e.g: broadcastMessage
        public void SendToAllClient(string name, string message)
        {
            // Call the addNewMessageToPage method to update clients.
            Clients.All.addNewMessageToPage(name, message);

            Clients.All.broadcastMessage(name, message);
        }

        public void SendToSpecificRoom(string name, string message, string roomName)
        {
            Clients.Group(roomName).addChatMessage(name, message);
        }
        #endregion



        #region with the concept of using GROUP or ROOM
        //In javascript, need to turn the first letter of a method name to small cap.
        public void JoinRoom(string username, string roomName)
        {
            Groups.Add(Context.ConnectionId, roomName);
            RoomBroadcast(username + " has joined into " + roomName, roomName);
        }

        public void LeaveRoom(string roomName)
        {
            Groups.Remove(Context.ConnectionId, roomName);
        }

        //In chat.chtml, the callback method is actually the client method name instead of method name. e.g: broadcastMessage
        public void RoomBroadcast(string message, string roomName)
        {
            Clients.Group(roomName).AddAnnouncement(roomName, message);
        }


       
        #endregion


        public void Typing(string username, string message)
        {
            if (!string.IsNullOrEmpty(message)) {
                Clients.All.addNewMessageToPage("typing", username + " is typing: " + message);
            }
            else
            {
                Clients.All.addNewMessageToPage("typing", "");
            }
        }
    }
}

2 comments:

  1. Hello Toh,
    The Article on Xamarin and Signal R - Chat Cross Platform is Awesome.The total programing is explained in the Above article ,Thanks for Sharing such an important information about Xamarin.Xamarin Apps Development

    ReplyDelete
  2. Hello I am so delighted I located your blog, I really located you by mistake, while I was watching on google for something else, Anyways I am here now and could just like to say thank for a tremendous post and a all round entertaining website. Please do keep up the great work. pakistani chatting room

    ReplyDelete

How to run unit test for your Xamarin Application in AppCenter?

How to run unit test for your Xamarin application in AppCenter?  When we talk about Building and Distributing your Xamarin app, you m...