Showing posts with label SignalR. Show all posts
Showing posts with label SignalR. Show all posts

Friday, February 6, 2015

Real time multi person multi window chat application using SignalR

This article is to demonstrate real time chat application using SignalR. I develop this code for my social network Alap.Me and it has tested with many people. This is super fast light weight and it can use many people at a time with multiple chat window. For alap.me due to window size I limit it to 4 active window. This looks as like gmail or facebook chat. My server was in UK and I tested it from India it's response time was around 0.350 second. That means when one person send message to some one, it deliver it in a popup within 0.350 second. I develop it as stand alone and later integrate it with alap.me. Similar way any one can use this ready-made code to his existing code. I am offering this as open source and any one can enhance this code by informing me (just a mail is ok) and its totally free of cost for non-profit purpose. 

Prerequisite 
This has developed based on .Net 4.5 with Visual Studio 2013 express.
I have setup it on Windows Server 2008.
IIS version 7.5 (or higher).
MySQL Database, however these has just 2 standard table you can create same in other database and can configure DB layer.

Technology Used
This is SignalR Hub based application with C# code.
HTML5, CSS3 and JavaScript used for UI development.
MySQL stored procedure with ADO.Net has used.
Code developed in Visual Studio 2013 Express for Web version used.

Basic Overview how it is working
Describing later this section.

Source code
Below picture is showing my full code file list which I am going to share at below.


ChatHub.cs

using System;
using System.Web;
using Microsoft.AspNet.SignalR;
using System.Data;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace SignalRChat
{
    public class ChatHub : Hub
    {
        AlapChat objChat;
        DataTable dt;
        static Hashtable htOnlineUsers = new Hashtable();
        static List<OnlineUser> OnlineUsers=new List<OnlineUser>();
        public ChatHub()
        {
            objChat = new AlapChat();
        }
        //public void Test(string str)
        //{
        //    Clients.Caller.Hello(str + " | Message received at server reply from server." + DateTime.Now.ToShortTimeString());
        //}
        //public void Friends123()
        //{
        //    dt = objChat.GetFriendLoginStatus("7");
        //    string onlineUserList = UtilityChat.DataTableToJson(dt);
        //    Clients.Caller.friendslist(onlineUserList);
        //}
        public void clean()
        {
           
            foreach (OnlineUser user in OnlineUsers)
            {
                objChat.SetOffline(user.MyId);
            }
            OnlineUsers.Clear();
           
        }
        public void Connect(string myid)
        {
            if(OnlineUsers.Count(x=>x.MyId==myid)==0)
            {
                OnlineUsers.Add(new OnlineUser { MyId = myid, ConnectionId = Context.ConnectionId });
            }
        }
        public void loginfriends(string myid,string name)
        {
            bool isOnline=false;
            if (OnlineUsers.Count(x => x.MyId == myid) == 0)
            {
                OnlineUsers.Add(new OnlineUser { MyId = myid, ConnectionId = Context.ConnectionId, Name = name });
                objChat.SetOnline(myid);              
            }
          else //User found in Array, check if ConnectionId is same or not, if not replace it in Array
            {
                OnlineUser user = OnlineUsers.FirstOrDefault(x => x.MyId == myid);
                if(user.ConnectionId!=Context.ConnectionId)
                {
                   // Clients.Caller.Hello("Remove and readd user.");
                    OnlineUsers.Remove(user);//Delete existing and add new user
                    OnlineUsers.Add(new OnlineUser { MyId = myid, ConnectionId = Context.ConnectionId, Name = name });
                }
            }
            dt = objChat.GetFriendLoginStatus(myid);
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["IsOnline"].ToString().ToLower() == "true" || dr["IsOnline"].ToString() == "1")
                    isOnline = true;
                else if (dr["IsOnline"].ToString().ToLower() == "false" || dr["IsOnline"].ToString() == "0")
                    isOnline = false;              
               
                //Inform all online friends that one user has logged in.
                if (isOnline)
                {
                    //Clients.Caller.Hello(isOnline.ToString() + " | Inform start." + DateTime.Now.ToShortTimeString());
                    try
                    {
                        OnlineUser onlineFriend = OnlineUsers.FirstOrDefault(x => x.MyId == dr["FriendUId"].ToString());
                        if (onlineFriend!=null)
                            Clients.Client(onlineFriend.ConnectionId).refreshfriendlist(myid, name); //Send new logged in user's information to all friends
                        else //User is online as DB entry but not exists in Array, hence need to set offline in DB
                        {
                            objChat.SetOffline(dr["FriendUId"].ToString());
                        }
                    }
                    catch(Exception ex)
                    {
                        Clients.Caller.Hello("Error! "+ex.Message+"<br/>"+ ex.StackTrace.ToString());
                    }
                    //Clients.Caller.Hello(isOnline.ToString() + " | Inform end." + DateTime.Now.ToShortTimeString());
                }
                else
                {
                    break;
                }
            }
           
            //Send online and offline friend list to caller
            string onlineUserList = UtilityChat.DataTableToJson(dt);
            Clients.Caller.friendslist(onlineUserList);
           
        }
        public void createnewchatid(string fromuid, string touid)
        {
            string newChatOrGroupId = objChat.GetNewChatOrGroupId();
            objChat.AddUserInChat(newChatOrGroupId,fromuid);
            objChat.AddUserInChat(newChatOrGroupId, touid);
            Clients.Caller.newchatid(newChatOrGroupId, touid);
        }
        public void sendpvtmsg(string chatorgroupid,string fromid, string fromname,string toid,string pvtmsg)
        {
            objChat.AddNewMessage(chatorgroupid, fromid, pvtmsg);
            OnlineUser onlineFriend = OnlineUsers.FirstOrDefault(x => x.MyId == toid);
            if (onlineFriend != null)
                Clients.Client(onlineFriend.ConnectionId).receivepvtmsg(chatorgroupid, fromid, fromname, pvtmsg);
        }
        public void nonmessage_control_info(string fromid, string fromname,string toid,string signal)//'Signal' is used to indicate, Typing, Away etc.
        {
            OnlineUser onlineFriend = OnlineUsers.FirstOrDefault(x => x.MyId == toid);
            if (onlineFriend != null)
                Clients.Client(onlineFriend.ConnectionId).incoming_control_msg(fromid, fromname, signal);
        }
       
        public override System.Threading.Tasks.Task OnDisconnected()
        {
            OnlineUser onlineUser = OnlineUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
            if (onlineUser != null)
            {
                bool isOnline = false;
                objChat.SetOffline(onlineUser.MyId);
                dt = objChat.GetFriendLoginStatus(onlineUser.MyId);
                foreach (DataRow dr in dt.Rows)
                {
                    if(dr["IsOnline"].ToString().ToLower() == "true" || dr["IsOnline"].ToString() == "1")
                        isOnline=true;
                    else if(dr["IsOnline"].ToString().ToLower() == "true" || dr["IsOnline"].ToString() == "1")
                        isOnline=false;
                    //Inform all online friends that one user has logged in.
                    if (isOnline)
                    {
                        OnlineUser onlineFriend = OnlineUsers.FirstOrDefault(x => x.MyId == dr["FriendUId"].ToString());
                        if (onlineFriend != null)
                        {
                            Clients.Client(onlineFriend.ConnectionId).logoffuser(onlineUser.MyId);
                          //  Clients.Client(onlineFriend.ConnectionId).incoming_control_msg(onlineUser.MyId, onlineUser.Name, "offline"); //Not developed, keep aside for future feature
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                OnlineUsers.Remove(onlineUser);
            }
            return base.OnDisconnected();
        }      
    }
    public class OnlineUser
    {
        //public OnlineUser(string MyId, string Name, string EmailId, string ConnectionId)
        //{
        //    this.myId = MyId;          
        //    this.connectionId = ConnectionId;
        //}
        public string MyId { get; set; }
        public string ConnectionId { get; set; }
        public string Name { get; set; }
    }
}





Tuesday, February 25, 2014

In Memory Search using Lamda Expression: Realtime Chat application on web in ASP.Net: Step 4

Welcome at  Realtime Chat application on web in ASP.Net using SignalR technology. This is step 4 and now we will learn how we can search in memory array without any loop like for, while etc. We will use Lamda expression to search an element in array list with generics. I shall not describe about these technologies from theoretical perspective, here I shall show some application of these. You can read theory of these things from MSDN site.

You may think why this is require for our chat application, really good question. We shall use this technique to find an online user in server. However we can take database help to find online users but to minimize database operation I have used this technique. In chat application I have used a public static list (array) to hold online users, and from here I am searching users to generate online friend lists. By that way I have minimize a lot database operation and this technique can improve your chat application.

Lets check the code first then shall describe the codes.

HTML/ASP.Net part
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <h1>In memory search using Lamda Expression in C#.Net</h1>
        <h3>Search country calling code</h3>
        <p>
            Country Name:
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
&nbsp;<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Find Calling Code" />
        </p>
        <p>
            <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
        </p>
        <a href="http://en.wikipedia.org/wiki/List_of_country_calling_codes" target="_blank">Full list is available here</a>
    </form>
</body>
</html>
and the C# code as below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
   
    protected void Page_Load(object sender, EventArgs e)
    {       
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        FindCallingCode();
    }
    private void FindCallingCode()
    {
        //In real use databind before searching, using by that way as demo
        List<Country> countries = new List<Country>();
        countries.Add(new Country { callingCode = "+91", name = "India" });
        countries.Add(new Country { callingCode = "+44", name = "UK" });
        countries.Add(new Country { callingCode = "+1", name = "USA" });
        countries.Add(new Country { callingCode = "+88", name = "Bangladesh" });
        countries.Add(new Country { callingCode = "+49", name = "Germany" });
        countries.Add(new Country { callingCode = "+33", name = "France" });
        countries.Add(new Country { callingCode = "+55", name = "Brazil" });

        Country country = countries.FirstOrDefault(x => x.name.ToLower() == TextBox1.Text.Trim().ToLower());
        if (country != null)
            Label1.Text = "Calling code of " + country.name + " is " + country.callingCode;
        else
            Label1.Text = TextBox1.Text + " Not Found in our Country List";
    }
}
public class Country {   
    public string callingCode { get; set; }
    public string name { get; set; }
}
Here is main method is  "FindCallingCode()" and class "Country". Here I am doing all operations. Lets look at some important code.

Country class: This class I have defined to create country objects which will store country name  and calling code. If you need extra properties you can add these easily.

List<Country> countries = new List<Country>();
In the above code I have defined a list (array) of county objects with name countries. Naming convention using as this variable holding multiple country hence its plural name of country.

countries.Add(new Country { callingCode = "+91", name = "India" });
In the above line of code I have adding element of array by creating country class object.

Country country = countries.FirstOrDefault(x => x.name.ToLower() == TextBox1.Text.Trim().ToLower());
This is actually Lamda expression "x=>x.name" this is doing searching operation with method "FirstOrDefault". This line searching all element and doing comparison with user entered country name and stored country name. When matched it will return the country object.
Label1.Text = "Calling code of " + country.name + " is " + country.callingCode;
 In previous line of code we have found country object from array of countries and now getting calling code and name from the found object.

In my chat application I have used mainly this (FirstOrDefault) method and for some cases have used "Count", "Find" methods/properties. "Find" and "FirstOrDefault" both can do a bit similar work but "Find" is very fast (in a blog I found 1000 times) than "FirstOrDefault", hence I am using as and when these are suitable.
For your knowledge you can check other methods as well.

Thanks for reading my blog please visit again for next article.

Source code is available here.

Thursday, February 20, 2014

Send client message to server using SignalR method - Realtime Chat application on web in ASP.Net: Step 3

This will be my 3rd post on SignalR technology. In previous post I shown how to get server time using SignalR client method, which will be called from server side. Now I shall show how to transfer data between server and client.

This is very simple solution and it can do as same way as normal .Net method calling with parameter.

I am not explaining these code again as I did it last time.

Startup.cs

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

ChatHub.cs file code:

using System;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRChat
{
    public class ChatHub : Hub
    {
        /// <summary>
        /// getservertime
        /// </summary>
        public void getservertime()
        {
            Clients.Caller.serverresponse("This is server response. Server is calling client method from server. <br/> Server time is: " + DateTime.Now.ToShortTimeString());
        }

        public void sendmessage(string usermessage)
        {
            Clients.Caller.serverresponse(usermessage + " :This is server message <br/>");
        }
    }
}
In this code I have added new method "sendmessage(parameter1)" and it will call same client method to return data to client. This is very simple code.


Next will come HTML part, which is as below:




<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   
    <title>SignalR Simple Chat</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <!--Reference the jQuery library. -->
    <script src="Scripts/json2.js"></script>
    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
   
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.0.0.js"></script>
    <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
   
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="/signalr/hubs"></script>
    <!--Add script to update the page and send messages.-->
   
    <script type="text/javascript">
$(function () {
    // Declare a proxy to reference the hub.
    var chat = $.connection.chatHub;


    //Write your server response related code here
    chat.client.serverresponse = function (message) {
        $('#dvServerResponse').append(message);
    };

    // Start the connection.
    $.connection.hub.start().done(function () {
        //Write your server invoke related code here
        $('#btnHello').click(function () {
            console.log('call server');
            chat.server.sendmessage($('#txt').val());
        });
    });
});
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
<div>
    Enter your message: <input type="text" id="txt" /><br />
    <input type="button" id="btnHello" value="Send message to server" />   

    <div id="dvServerResponse"></div>   
   
</div>
    </div>
    </form>
</body>
</html>
When you will run this in browser it will show as below:


Hope you have enjoyed this post and please visit my blog again.

Next will show something about Lamda Expression which I shall use in my chat application.



Wednesday, February 19, 2014

Get Server time - Realtime Chat application on web in ASP.Net using SignalR Technology: Step 2

In previous post I have describe how to set up your project for SignalR with require software. Now I shall show to get server time and how can invoke a server method as request and how can get response with server time by calling client javascript method from server end.
Again here will be these main part of coding and here I am not changing anything in Startup.cs file. This code as it is.

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

Next is ChatHub.cs and here is very small code as below:

using System;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRChat
{
    public class ChatHub : Hub
    {
        public void getservertime()        {
            Clients.Caller.serverresponse("This is server response. Server is calling client method from server.
Server time is: " + DateTime.Now.ToShortTimeString());
        }
    }
}

Here I have added on public method "getservertime()". Note here I have written all method in small letters and shall call this from client javascript in small letters only. Previously I have tested by writing in capital letters and have seen this is not working. So I would suggest to write these methods always in small letters only, to avoid difficulties.

"getservertime()" is very small method which will invoked by client on button press and this method will invoke a client's javascript method to send response to client. Note here I am writting 'Clients.Caller' to find out the client from where server method has invoked. If I need to call any different client's method (usually for chat application one user will send method to other, so one client will invoke server method and server method will call other client's client method. These things I shall show later) then there will be some different way, which I shall explain later. After 'Client.Caller' method name is coming that is "serverresponse()". This client method is passing argument and this will deliver server message to client.

Next I shall explain about client code and these all are HTML and Javascript only.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   
    <title>SignalR Simple Chat</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <!--Reference the jQuery library. -->
    <script src="Scripts/json2.js"></script>
    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
   
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.0.0.js"></script>
    <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
   
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="/signalr/hubs"></script>
    <!--Add script to update the page and send messages.-->
   
    <script type="text/javascript">
$(function () {
    // Declare a proxy to reference the hub.
    var chat = $.connection.chatHub;


    //Write your server response related code here
    chat.client.serverresponse = function (message) {
        $('#dvServerResponse').append(message);
    };

    // Start the connection.
    $.connection.hub.start().done(function () {
        //Write your server invoke related code here
        $('#btnHello').click(function () {
            console.log('call server');
            chat.server.getservertime();
        });
    });
});
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
<div>
    <div id="dvServerResponse"></div>   
    <input type="button" id="btnHello" value="Get Server Time" />   
</div>
    </div>
    </form>
</body>
</html>

These HTML and Javascript code I have written in ASP.Net file however this will work in normal HTML file as well.
Initial part is javascript library file referencing section. Here I am calling files in three steps, first JSON and JQeury files, next SignalR library and finally Hub files. Next starting custom java script codes.

In java script code firstly I have created a proxy of chatHub. Next code is

//Write your server response related code here
    chat.client.serverresponse = function (message) {
        $('#dvServerResponse').append(message);
    };

For time being you can assume this is standard syntax of creating client methods which will be called from server and within this cal implement client activities. For my case I am appending server response at div.

Other part of client codes as below

//Write your server invoke related code here
$('#btnHello').click(function () {
    console.log('call server');
    chat.server.getservertime();
});

This method will start executing once btnHello clicked and it will invoke server method to get server response. Here to invoke server method syntax like "chat.server.getservertime()" or "proxy-object.server.server-method()".

Finally result will displayed in client browser.

Here is the full code.

Thanks for reading my blog.



Tuesday, February 18, 2014

SignalR - Hello World: Real time chat application on Web in ASP.Net using SignalR technology : Step 1


Programming with distributed technology is my passion. Earlier I have worked with Remoting, Socket, Web Service and a bit with WCF. So when I first came to know about SignalR technolog, really I can not wait to start coding on it. Now I can able to write own chat application for AlapMe and really its working fine. Most of all by using SignalR I can use socket of HTML5. I shall write multiple posts on SignalR as tutorial as I did in past with C# Socket programming. I shall publish these posts on this blog and on my socket programming blog as well.
I have started SignalR programming with Visual Studio Express 2013 which is freely downloadable from here. Also you can read full documentation from Microsoft from this link. As my target to share some practical example with ready to use code hence I shall not describe in detail about the technology. You can follow Microsoft documentation website for it.
To start with SignalR first coding you need to follow steps are below.
Lunch your VS 2013 and create a blank project and add new item of SignalR Hub Class (v2) set its name as you wish, for my case its MyHub.cs. When you will add this class Visual Studio automatically add all related references and jquery classes. To add these things it may take some time may be 2-3 minutes. This new item will come with a sample method 'Hello()', for now just follow these later I shall describe what is these things and why these are. Full code will look like below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalR_Learning
{
    public class MyHub : Hub
    {
        public void Hello()
        {
            Clients.All.hello();
        }
    }
}
Now go to next step and add next item in project, that is OWIN Startup class. I am giving its default name 'Startup1.cs' for my sample project. Visual Studio will create this file with some pre-added code. We will extend these code as per your needs. Code as below:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalR_Learning.Startup1))]
namespace SignalR_Learning
{
    public class Startup1
    {
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
        }
    }
}
In method Configuration I shall add just a line of code 'app.MapSignalR();' so full method will look like:
public void Configuration(IAppBuilder app)
{
    // For more information on how to configure your application, visit      http://go.microsoft.com/fwlink/?LinkID=316888
    app.MapSignalR();
}
 Now we will move to front end coding and this part will develop with simple HTML page, however you can use ASPX page as well. Now I have added a HTML page with name 'index.html'
<! DOC TYPE ht ml >
< ht ml xmlns="http://www.w3.org/1999/xhtml" >
    SignalR Simple Chat
    "X-UA-Compatible" content="IE=edge" / >
    
    
     < sc ript src="Scripts/jquery-1.10.2.js">
    < sc ript src="Scripts/jquery-1.10.2.min.js">
   
    < scri pt src="Scripts/json2.js">
    
    "Scripts/jquery.signalR-2.0.0.js">
    "Scripts/jquery.signalR-2.0.0.min.js">
    
    "/signalr/hubs">
    
    "text/ ">
        var chat;
        $(f unction () {
            // Declare a proxy to reference the hub.
            //chat = $.hubConnection.myhub;
            chat = $.connection.myhub;
            //alert(chat);
            chat.client.hello = function (message) {
                alert(message);
            };
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#btnhello').click(function () {                   
                    alert(chat);
                });
            });
        });
    

    "button" value="Hello" id="btn hello" />



 
 


Tuesday, January 14, 2014

Real time chat application on Web in ASP.Net using SignalR technology : Introduction

I shall start posting code and description about how to create web chat application in asp.net using .Net's latest technology SignalR step by step. Also I shall share how to create server event based application. Already I have developed this chat server and using in my social website http://alap.me.

However I shall start posting on it step by step so a learner can learn it easily. I shall start from very begging with many small small things and shall cover ASP.Net parts and related stuff like jQuery, CSS, HTML5 or normal java script. Because all of these things will require to build full complete chat application.

The same code I shall share which I have used in my social network site chat part. I shall publish my code as open source so any one can use it in his application and any one can enhance it so other people can use it as like Linux did in early days. To use my chat application code just they need to mention in somewhere in this website (say at footer) a thanks to me with my personal website url that is http://sumanbiswas.com and just drop me a mail that they are using my code for my information. Whole code will be totally free of cost.

So this is my introduction of chat application source code and from next I shall post it by step by step.

Sunday, December 22, 2013

Hello World with SignalR

[Original Post from my blog OnlyMS.Net for better visibility read it from OnlyMS.Net]  

Programming with distributed technology is my passion. Earlier I have worked with Remoting, Socket, Web Service and a bit with WCF. So when I first came to know about SignalR technolog, really I can not wait to start coding on it. Now I can able to write own chat application for AlapMe and really its working fine. Most of all by using SignalR I can use socket of HTML5. I shall write multiple posts on SignalR as tutorial as I did in past with C# Socket programming. I shall publish these posts on this blog and on my socket programming blog as well.

I have started SignalR programming with Visual Studio Express 2013 which is freely downloadable from here. Also you can read full documentation from Microsoft from this link. As my target to share some practical example with ready to use code hence I shall not describe in detail about the technology. You can follow Microsoft documentation website for it. 

To start with SignalR first coding you need to follow steps are below.
Lunch your VS 2013 and create a blank project and add new item of SignalR Hub Class (v2) set its name as you wish, for my case its MyHub.cs. When you will add this class Visual Studio automatically add all related references and jquery classes. To add these things it may take some time may be 2-3 minutes. This new item will come with a sample method 'Hello()', for now just follow these later I shall describe what is these things and why these are. Full code will look like below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalR_Learning
{
    public class MyHub : Hub
    {
        public void Hello()
        {
            Clients.All.hello();
        }
    }
}


Now go to next step and add next item in project, that is OWIN Startup class. I am giving its default name 'Startup1.cs' for my sample project. Visual Studio will create this file with some pre-added code. We will extend these code as per your needs. Code as below:

 

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalR_Learning.Startup1))]
namespace SignalR_Learning
{
    public class Startup1
    {
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
        }
    }
}
 In method Configuration I shall add just a line of code 'app.MapSignalR();' so full method will look like:

 

public void Configuration(IAppBuilder app)
{
    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
    app.MapSignalR();
}
 Now we will move to front end coding and this part will develop with simple HTML page, however you can use ASPX page as well. Now I have added a HTML page with name 'index.html'

  < me ta http-equiv="X-UA-Compatible" content="IE=edge" / >

    < ! --Script references. -->
    < ! --Reference the jQuery library. -->
    < s cript src="Scripts/jquery-1.10.2.js">< / scr ipt>
    < s cript src="Scripts/jquery-1.10.2.min.js">< / scr ipt>   
    < s cript src="Scripts/json2.js"></ scr ipt>
    < ! --Reference the SignalR library.  - - >
    < s cript src="Scripts/jquery.signalR-2.0.0.js">< / scr ipt>
    < s cript src="Scripts/jquery.signalR-2.0.0.min.js">< / scri pt>
    < ! --Reference the autogenerated SignalR hub script. - - >
    "/signalr/hubs">
    < ! --Add script to update the page and send messages.-- >

 < s cript type="text/java scri pt" >

        var chat;
        $(function () {
            // Declare a proxy to reference the hub.
            //chat = $.hubConnection.myhub;
            chat = $.connection.myhub;
            //alert(chat);
            chat.client.hello = function (message) {
                alert(message);
            };
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#btnhello').click(function () {                   
                    alert(chat);
                });
            });
        });
< / scr ipt> 
 < in put ty pe="button" value="Hello" id="btnhello" / >

 

 Thank you for visiting my blog.

 

Wednesday, July 17, 2013

Small File Transfer Client to Client (via Server) using C#.Net socket programming



After long days I am writing this article and this is the complete package of these all articles about file transfer from one computer to another. Till now I have shown how to transfer file from client to server or server to client. But now I am merging these two things and creating one single application which can send data/file from one client to another client. It seems data is going directly from one client to another but actually it’s rotating via Server, I will explain here these things.

I am planning to stop this article series on Socket Programming in Desktop using C#.Net here for now and ignoring large file transfer sample from client to client because now a day is era of Web Programming. Long ago I tried to write code in web application with socket but I failed because web and desktop is totally different type of architecture. 

But in HTML5 is very powerful and it has introduced new thing to develop socket programming on web as well. In HTML5 there has Web Socket and using Web Socket Micorsoft has created SignalR which will be my next attraction of discussion. I shall try to explain and shall create multiple applications including Web Chat, message broadcasting system using these technologies. 

Before going to discuss Client to Client application I would like to recap earlier two post:


I am trying to explain how these were working.

   File Transfer from Client to Server

Server
Client
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.








5. Server receive client request and accept it. Once connection established, server create another socket object which will handle this client all requests until connection ends. Client will be informed internally by TCP about connect success.

6. Start preparations to store incoming byte data from client.



8. Server receives file byte data along with file name and stores it in byte array.

9. Server retrieve file name from byte data.

10. Server opens a binary stream writer with file name to store byte data in it. 

11. Once file save complete server closes binary stream writer and server socket objects.



14 Server program ends here.



2. Client creates an IP End Point and a socket object. 

3. Prepare byte data from file which will be sent to server.

4. Try to connect to server using client socket by help of IP end point.









7. Client starts sending byte data over connected socket.











12. Once data transfer complete and server closes socket connection, client also close client socket object.

13. Client program work ends here.



File Transfer from Client to Server
Server
Client
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.





4. Server receive client request and accept it. Once connection established, server create another socket object which will handle this client all requests until connection ends. Client will be informed internally by TCP about connect success.




6. Prepare byte data from file which will be sent to client.

7. Server starts sending byte data over connected socket.











12. Once data transfer complete and client closes socket connection, server also close server socket object.

13. Server program work ends here.



2. Client creates an IP End Point and a socket object.

3. Try to connect to server using client socket by help of IP end point.







5. Start preparations to store incoming byte data from server.






8. Client receives file byte data along with file name and stores it in byte array.

9. Client retrieve file name from byte data.

10. Client opens a binary stream writer with file name to store byte data in it.

11. Once file save complete client closes binary stream writer and server socket objects.






14. Client program work ends here.

So from these two tables it’s clear that in (1) Client to Server data transfer and (2) Server to Client program server and client is doing just like opposite execution.
 


When we transfer file over internet one client cannot connect to another directly because maximum client do not use static/global IP, so they cannot reach over other internet location directly. So to transfer file from client to client need server help. Server stays internet with a static IP which is accessible globally.  We will use server as temporary storage and to connect other client via server. Overall architecture will be as below:



In above picture, Client A is trying to send file to client B and both are taking help of Server in between to make connection. Client A and B both are inaccessible from outside internet because these are may be in DHCP inside a LAN or its IP has generated by some other local router. So both will connect to server and transfer data.
Now follow below communication chart to understand how data will be transferred. This chart is combination of first two chart. 


      Data Transfer      -- > -------------->-----------------------> -------------->----------------------->
Client A
Server
Client B





2. Client-A create IP End Point and a socket object.



4. Client A Prepare byte data from file which will be sent to server.

5. Client A tries to connect server using client socket by help of IP end point.





















8. Connection established with client A and server.







11. Client A starts sending byte data over connected socket.





































20. Client A receive file transfer success message from server.







22. Socket object closes and dispose.





24. Client A process ends here.
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.

















7. Server receives two client requests and accept these. Once connection established, server create new socket object for each connection (here total two, suppose sockObjectA for Client A and sockObjectB for Client B). These will handle client’s all requests until connection ends. Client will be informed internally by TCP about connect success. In our case sockObjectA will receive data and sockObjectB will send data.
For real life application can use socket object list (say array list or hash table) with some hash table to track client name and socket object name.






10. Start preparations to store incoming byte data from client A through sockObjectA.




12. Server receives file byte data along with file name and stores it in byte array. For large file can store in temporary file but I would suggest to store in array for faster processing. 

13. Server starts sending byte data over connected socket sockObjectB to client B.






















19. Server receive EOF successful message from client B and pass information to client A about file transfer success.





21. Server initiate to disconnect socket connection for sockObjectA and sockObjectB, so connection break with server and client A and B.
















26. Server process ends here for my case. For real life project server will stay in listen mode for next client request.








3. Client B creates IP End Point and a socket object.








6. Client B tries to connect server using client socket by help of IP end point.




















9. Connection established with client A and server.

















14. Client B receives file byte data along with file name and stores it in byte array.

15. Client retrieve file name from received byte data.

16. Client opens a binary stream writer with file name to store byte data in it.

17. Once file save complete client (do some technique to understand End Of File - EOF) closes binary stream writer and server socket objects.

18. Send a message to server to inform client A about file transfer success.


















23. Socket object closes and dispose.






25. Client B process here.
If you send large file then logic will be same and you need to loop step 11 to 20 until file ends. Here I have used EOF and then can use some fixed data packet every time. So once each packet receive in Client B, it will inform that successful receive of packet number and ask server to send next packet. 

For large file server will store file temporarily because connection speed in client A and B may not be same. Client A can send much faster data but client B may get it very slow. So buffering concept need to implement in server.

If possible I shall write this code in future.

Now I am posting this logic next will write code and once finish will post it for you with downloadable source code.