Implement of private one to one chat between database table users with SignalR
In this blog I will discuss How Implement of private one to one chat between database table users with SignalR? SignalR is used for real time communication in ASP.NET. I will create separate user control for chat application. Please check below How to I implement it.
Step 1: Install SignalR from nuget to application.
Tools>Library Package Manager>Package Manager Console
Type following command in Manager Console: Install-Package Microsoft.AspNet.SignalR
SignalR will added in reference also
Step 2: Add ChatHub, MessageDetail & UserDetail Classes
Register SignarR on Startup Class
Step 3: I am using jQuery UI Chatbox Plugin(http://magma.cs.uiuc.edu/wenpu1/chatbox.html) in project
Github source code(https://github.com/dexterpu/jquery.ui.chatbox)
Give reference of css & js file of Jquery Chat Box Plugin. It will start working.
Step 4: Add notify.mp3 in directory which will play on message alert.
Step 5: Add chatboxManager.js file in project.
Step 6: Add new Web User Control
Right click on solution> Add New Item> Select Web User Control
I renamed it to ctlChatBox.ascx
Add following code in user control.
Add following code in ctlChatBox.ascx.cs
That's it run project & Start Chat.
You can download the source code of the application from github.
https://github.com/shivam01990/SignalR-private-one-to-one-chat
Step 1: Install SignalR from nuget to application.
Tools>Library Package Manager>Package Manager Console
Type following command in Manager Console: Install-Package Microsoft.AspNet.SignalR
SignalR will added in reference also
Step 2: Add ChatHub, MessageDetail & UserDetail Classes
public class MessageDetail { public int FromUserID { get; set; } public string FromUserName { get; set; } public int ToUserID { get; set; } public string ToUserName { get; set; } public string Message { get; set; } } public class UserDetail { public string ConnectionId { get; set; } public int UserID { get; set; } public string UserName { get; set; } } [HubName("chatHub")] public class ChatHub : Hub { #region---Data Members--- static List<UserDetail> ConnectedUsers = new List<UserDetail>(); static List<MessageDetail> CurrentMessage = new List<MessageDetail>(); #endregion #region---Methods--- public void Connect(string UserName, int UserID) { var id = Context.ConnectionId; if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0) { ConnectedUsers.Add(new UserDetail { ConnectionId = id, UserName = UserName + "-" + UserID, UserID = UserID }); } UserDetail CurrentUser = ConnectedUsers.Where(u => u.ConnectionId == id).FirstOrDefault(); // send to caller Clients.Caller.onConnected(CurrentUser.UserID.ToString(), CurrentUser.UserName, ConnectedUsers, CurrentMessage, CurrentUser.UserID); // send to all except caller client Clients.AllExcept(CurrentUser.ConnectionId).onNewUserConnected(CurrentUser.UserID.ToString(), CurrentUser.UserName, CurrentUser.UserID); } public void SendMessageToAll(string userName, string message) { // store last 100 messages in cache //AddMessageinCache(userName, message); // Broad cast message //Clients.All.messageReceived(userName, message); } public void SendPrivateMessage(string toUserId, string message) { try { string fromconnectionid = Context.ConnectionId; string strfromUserId = (ConnectedUsers.Where(u => u.ConnectionId == Context.ConnectionId).Select(u => u.UserID).FirstOrDefault()).ToString(); int _fromUserId = 0; int.TryParse(strfromUserId, out _fromUserId); int _toUserId = 0; int.TryParse(toUserId, out _toUserId); List<UserDetail> FromUsers = ConnectedUsers.Where(u => u.UserID == _fromUserId).ToList(); List<UserDetail> ToUsers = ConnectedUsers.Where(x => x.UserID == _toUserId).ToList(); if (FromUsers.Count != 0 && ToUsers.Count() != 0) { foreach (var ToUser in ToUsers) { // send to //Chat Title Clients.Client(ToUser.ConnectionId).sendPrivateMessage(_fromUserId.ToString(), FromUsers[0].UserName, FromUsers[0].UserName, message); } foreach (var FromUser in FromUsers) { // send to caller user //Chat Title Clients.Client(FromUser.ConnectionId).sendPrivateMessage(_toUserId.ToString(), FromUsers[0].UserName, ToUsers[0].UserName, message); } // send to caller user //Clients.Caller.sendPrivateMessage(_toUserId.ToString(), FromUsers[0].UserName, message); //ChatDB.Instance.SaveChatHistory(_fromUserId, _toUserId, message); MessageDetail _MessageDeail = new MessageDetail { FromUserID = _fromUserId, FromUserName = FromUsers[0].UserName, ToUserID = _toUserId, ToUserName = ToUsers[0].UserName, Message = message }; AddMessageinCache(_MessageDeail); } } catch { } } public void RequestLastMessage(int FromUserID, int ToUserID) { List<MessageDetail> CurrentChatMessages = (from u in CurrentMessage where ((u.FromUserID == FromUserID && u.ToUserID == ToUserID) || (u.FromUserID == ToUserID && u.ToUserID == FromUserID)) select u).ToList(); //send to caller user Clients.Caller.GetLastMessages(ToUserID, CurrentChatMessages); } public void SendUserTypingRequest(string toUserId) { string strfromUserId = (ConnectedUsers.Where(u => u.ConnectionId == Context.ConnectionId).Select(u => u.UserID).FirstOrDefault()).ToString(); int _toUserId = 0; int.TryParse(toUserId, out _toUserId); List<UserDetail> ToUsers = ConnectedUsers.Where(x => x.UserID == _toUserId).ToList(); foreach (var ToUser in ToUsers) { // send to Clients.Client(ToUser.ConnectionId).ReceiveTypingRequest(strfromUserId); } } public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) { var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId); if (item != null) { ConnectedUsers.Remove(item); if (ConnectedUsers.Where(u => u.UserID == item.UserID).Count() == 0) { var id = item.UserID.ToString(); Clients.All.onUserDisconnected(id, item.UserName); } } return base.OnDisconnected(stopCalled); } #endregion #region---private Messages--- private void AddMessageinCache(MessageDetail _MessageDetail) { CurrentMessage.Add(_MessageDetail); if (CurrentMessage.Count > 100) CurrentMessage.RemoveAt(0); } #endregion }
Register SignarR on Startup Class
[assembly: OwinStartup(typeof(MyProject.Chat.Startup))] namespace MyProject.Chat { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } }
Step 3: I am using jQuery UI Chatbox Plugin(http://magma.cs.uiuc.edu/wenpu1/chatbox.html) in project
Github source code(https://github.com/dexterpu/jquery.ui.chatbox)
Give reference of css & js file of Jquery Chat Box Plugin. It will start working.
Step 4: Add notify.mp3 in directory which will play on message alert.
Step 5: Add chatboxManager.js file in project.
var chatHub = $.connection.chatHub; $(document).ready(function () { $('<audio id="chatAudio"><source src="' + srp + 'images/notify.ogg" type="audio/ogg"><source src="' + srp + 'images/notify.mp3" type="audio/mpeg"><source src="' + srp + 'images/notify.wav" type="audio/wav"></audio>').appendTo('body'); // Declare a proxy to reference the hub. var chatHub = $.connection.chatHub; registerClientMethods(chatHub); // Start Hub $.connection.hub.start().done(function () { registerEvents(chatHub); }); $("#chat_min_button").click(function () { if ($(this).html() == "<i class=\"fa fa-minus-square\"></i>") { $(this).html("<i class=\"fa fa-plus-square\"></i>"); } else { $(this).html("<i class=\"fa fa-minus-square\"></i>"); } $("#chat_box").slideToggle(); }); setInterval(ResetTypingFlag, 6000); }); function registerEvents(chatHub) { var UserName = $("[id$=hdnCurrentUserName]").val(); var UserID = parseInt($("[id$=hdnCurrentUserID]").val()); chatHub.server.connect(UserName, UserID); } function registerClientMethods(chatHub) { // Calls when user successfully logged in chatHub.client.onConnected = function (id, userName, allUsers, messages, userid) { $('#hdId').val(id); $('#hdUserName').val(userName); // Add All Users for (i = 0; i < allUsers.length; i++) { //AddUser(chatHub, allUsers[i].ConnectionId, allUsers[i].UserName, userid); AddUser(chatHub, allUsers[i].UserID, allUsers[i].UserName, userid); } // Add Existing Messages for (i = 0; i < messages.length; i++) { AddMessage(messages[i].UserName, messages[i].Message); } } } // On New User Connected chatHub.client.onNewUserConnected = function (id, name, userid) { AddUser(chatHub, id, name, userid); } // On User Disconnected chatHub.client.onUserDisconnected = function (id, userName) { $('#' + id).remove(); //var ctrId = 'private_' + id; //$('#' + ctrId).remove(); } chatHub.client.messageReceived = function (userName, message) { AddMessage(userName, message); } chatHub.client.sendPrivateMessage = function (windowId, fromUserName, chatTitle, message) { var ctrId = 'private_' + windowId; if ($('#' + ctrId).length == 0) { createPrivateChatWindow(chatHub, windowId, ctrId, fromUserName, chatTitle); $('#chatAudio')[0].play(); } else { var rType = CheckHiddenWindow(); if ($('#' + ctrId).parent().css('display') == "none") { $('#' + ctrId).parent().parent().effect("shake", { times: 2 }, 1000); rType = true; } if (rType == true) { $('#chatAudio')[0].play(); } } $('#' + ctrId).chatbox("option", "boxManager").addMsg(fromUserName, message); $('#typing_' + windowId).hide(); } chatHub.client.GetLastMessages = function (TouserID, CurrentChatMessages) { //debugger; var ctrId = 'private_' + TouserID; var AllmsgHtml = ""; for (i = 0; i < CurrentChatMessages.length; i++) { AllmsgHtml += "<div style=\"display: block; max-width: 200px;\" class=\"ui-chatbox-msg\">"; if (i == CurrentChatMessages.length - 1) { if ($('#' + ctrId).children().last().html() != "<b>" + CurrentChatMessages[i].FromUserName + ": </b><span>" + CurrentChatMessages[i].Message + "</span>") { AllmsgHtml += "<b>" + CurrentChatMessages[i].FromUserName + ": </b><span>" + CurrentChatMessages[i].Message + "</span>"; } } else { AllmsgHtml += "<b>" + CurrentChatMessages[i].FromUserName + ": </b><span>" + CurrentChatMessages[i].Message + "</span>"; } AllmsgHtml += "</div>"; } $('#' + ctrId).prepend(AllmsgHtml); } function CheckHiddenWindow() { var hidden, state; if (typeof document.hidden !== "undefined") { state = "visibilityState"; } else if (typeof document.mozHidden !== "undefined") { state = "mozVisibilityState"; } else if (typeof document.msHidden !== "undefined") { state = "msVisibilityState"; } else if (typeof document.webkitHidden !== "undefined") { state = "webkitVisibilityState"; } if (document[state] == "hidden") return true; else return false; } function AddUser(chatHub, id, name, userid) { var currentuserid = parseInt($("[id$=hdnCurrentUserID]").val()); var connectionid = $('#hdId').val(); var code = ""; if (connectionid == "") { if (userid == currentuserid) { $('#hdId').val(id); connectionid = id; $('#hdUserName').val(name); } } if (connectionid != id) { if ($('#' + id).length == 0) { code = $('<a id="' + id + '" class="col-sm-12 bg-success" > <i class=\"fa fa-user\"></i> ' + name + '<a>'); $(code).dblclick(function () { var id = $(this).attr('id'); if (connectionid != id) { OpenPrivateChatWindow(chatHub, id, name); } }); } } else { if ($('#curruser_' + id).length == 0) { code = $('<div id="curruser_' + id + '" class="col-sm-12 bg-info" ><i class=\"fa fa-user\"></i> ' + name + '<div>'); } } $("#chat_box").append(code); } function OpenPrivateChatWindow(chatHub, id, userName) { var ctrId = 'private_' + id; if ($('#' + ctrId).length > 0) return; createPrivateChatWindow(chatHub, id, ctrId, userName, userName); } function createPrivateChatWindow(chatHub, userId, ctrId, userName, chatTitle) { $("#chat_div").append("<div id=\"" + ctrId + "\"></div>") showList.push(ctrId); $('#' + ctrId).chatbox({ id: ctrId, title: chatTitle, user: userName, offset: getNextOffset(), width: 200, messageSent: function (id, user, msg) { chatHub.server.sendPrivateMessage(userId, msg); TypingFlag = true; }, boxClosed: function (removeid) { $('#' + removeid).remove(); var idx = showList.indexOf(removeid); if (idx != -1) { showList.splice(idx, 1); diff = config.width + config.gap; for (var i = idx; i < showList.length; i++) { offset = $("#" + showList[i]).chatbox("option", "offset"); $("#" + showList[i]).chatbox("option", "offset", offset - diff); } } } }); $('#' + ctrId).siblings().css("position", "relative"); $('#' + ctrId).siblings().append("<div id=\"typing_" + userId + "\" style=\"width:20px; height:20px; display:none; position:absolute; right:14px; top:8px\"><img height=\"20\" src=\"" + srp + "images/pencil.gif\" /></div>"); $('#' + ctrId).siblings().find('textarea').on('input', function (e) { if (TypingFlag == true) { chatHub.server.sendUserTypingRequest(userId); } TypingFlag = false; }); var FromUserID = parseInt($("[id$=hdnCurrentUserID]").val()); var ToUserID = userId; chatHub.server.requestLastMessage(FromUserID, ToUserID); } chatHub.client.ReceiveTypingRequest = function (userId) { var ctrId = 'private_' + userId; if ($('#' + ctrId).length > 0) { jQuery('#typing_' + userId).show(); jQuery('#typing_' + userId).delay(6000).fadeOut("slow"); } } // list of boxes shown on the page var showList = new Array(); var config = { width: 200, //px gap: 20, maxBoxes: 5 }; var getNextOffset = function () { return (config.width + config.gap) * showList.length; }; var TypingFlag = true; function ResetTypingFlag() { TypingFlag = true; } function AddMessage(userName, message) { //$('#divChatWindow').append('<div class="message"><span class="userName">' + userName + '</span>: ' + message + '</div>'); //var height = $('#divChatWindow')[0].scrollHeight; //$('#divChatWindow').scrollTop(height); }
Step 6: Add new Web User Control
Right click on solution> Add New Item> Select Web User Control
I renamed it to ctlChatBox.ascx
Add following code in user control.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ctlChatBox.ascx.cs" Inherits="controls_ctlChatBox" %> <div id="chat_widnow"> <div id="chat_title_bar"> <span class="col-sm-9 text-primary"><strong>Online Users</strong></span> <div id="chat_min_button"><i class="fa fa-plus-square"></i></div> </div> <div id="chat_box" style="display: none;overflow-y:auto;"> </div> </div> <div id="chat_div"></div> <input id="hdId" type="hidden" /> <input id="hdUserName" type="hidden" /> <asp:HiddenField ID="hdnCurrentUserName" runat="server" /> <asp:HiddenField ID="hdnCurrentUserID" runat="server" /> <script src="<%=Page.ResolveUrl("~") %>scripts/jquery.signalR-2.2.0.min.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="<%=Page.ResolveUrl("~") %>signalr/hubs"></script> <link href="<%=Page.ResolveUrl("~") %>styles/jquery.ui.chatbox.css" rel="stylesheet" /> <script src="<%=Page.ResolveUrl("~") %>scripts/jquery.ui.chatbox.js"></script> <script src="<%=Page.ResolveUrl("~") %>scripts/chatboxManager.js"></script>
protected void Page_Load(object sender, EventArgs e) { hdnCurrentUserName.Value = GetCurrentUserName(); hdnCurrentUserID.Value = GetCurrentUserID(); }
You can download the source code of the application from github.
https://github.com/shivam01990/SignalR-private-one-to-one-chat
ASP.NET , Java Script , Jquery
Thanks, that's what I am looking for.
ReplyDeleteImplementation of this code will be available soon.
ReplyDeleteThanks
thanks shivam,
Deleteis it possible to communicate you? I would send you the issue I am facing.
Implementation of this is available now.
ReplyDeleteI want send message offline for user? you can help me! thanks
ReplyDeleteHow can get list user when user offline?
ReplyDeleteDisplay Offline users & receive Offline messages are not implemented in the current application
Deleteoh, I need to work with it :(
DeleteI have problem is change setup status for user
Deletehey boys!
ReplyDeleteHow do I send a message to an offline user in a SignalR chat program? Please hepl me!
Hey,
DeleteHave you find out how to send and receive messages to Offline users?
Hello bro..i wnt to save messages in database using this code plz help me
ReplyDeletecan anyone tell me that what is "GetCurrentUserName()" in ctlChatBox.ascx.cs ??
ReplyDeleteLooking for an MVC version of this project?
ReplyDeleteMVC version is not available but you can integrate it easily.
Deleteone file is missing in this application...
Deletethat is signalr/hubs this file is missing
Please need mvc5 version
Deletecould not integrate it easily
I will add MVC version of this project soon.
Deletedo you already have a MVC version of this , thanks thanks
ReplyDeleteThis comment has been removed by the author.
ReplyDelete