search
HomeBackend DevelopmentC#.Net TutorialAsp.net uses SignalR to implement cool end-to-end chat function

1. Introduction

  In the previous article, SignalR has been introduced in detail, and its application in Asp.net MVC and WPF has been briefly introduced. The last blog post introduced the implementation of group messaging. However, SignalR was born for real-time chat, so it naturally lacks the end-to-end chat unlike QQ. This blog post will introduce how to use SignalR to implement functions similar to QQ chat.

2. The idea of ​​using SignalR to implement end-to-end chat

Before introducing the specific implementation, I first introduced the idea of ​​using SignalR to implement end-to-end chat. I believe you have seen code like Clients.All.sendMessage(name, message); in the previous article, which means calling SendMessage of all clients. SignalR's hub enables real-time communication between clients and servers. To achieve end-to-end chat, naturally you cannot send messages to all clients, but can only send messages to specific clients. Otherwise, it will be chaotic and there will be no privacy. So how can I send a message to a specific client? This problem is the key to our implementation of end-to-end chat function.

 In addition to the All attribute, the Clients object we send also has other attributes. You can press F12 in VS to view all attributes or methods of the Clients object. The specific definition is as follows:

public interface IHubConnectionContext<T>
{
T All { get; } // 代表所有客户端
 
T AllExcept(params string[] excludeConnectionIds); // 除了参数中的所有客户端
T Client(string connectionId); // 特定的客户端,这个方法也就是我们实现端对端聊天的关键
T Clients(IList<string> connectionIds); // 参数中的客户端端
T Group(string groupName, params string[] excludeConnectionIds); // 指定客户端组,这个也是实现群聊的关键所在
T Groups(IList<string> groupNames, params string[] excludeConnectionIds);
T User(string userId); // 特定的用户
T Users(IList<string> userIds); // 参数中的用户
}

In SignalR, every To mark a client's uniqueness, SignalR will assign it a ConnectionId, so that we can find the specific client through the ConnectionId. In this way, when we send a message to a client, in addition to passing in the message, we also need to enter the ConnectionId sent to the other party, so that the server can forward the corresponding message to the corresponding client based on the incoming ConnectionId. Served. This completes the end-to-end chat function. In addition, if the user is not online, the server can save the message to the database. When the corresponding client comes online, it can check from the database whether the client has any messages that need to be pushed. If so, retrieve the data from the database. , push the data to the client. (However, the function of caching data on the server side is not implemented in this blog post. The introduction here is to let everyone understand one of the implementation principles of QQ).

Let’s sort out the implementation ideas of the end-to-end chat function:

When the client logs in, it records the client’s ConnectionId and adds the user to a static array. This data is used to record all online users.
Users can click on the user chat among online users. When sending a message, the ConnectionId needs to be passed to the server.
The server calls the Clients.Client(connnection).sendMessage method based on the incoming message content and ConnectionId to forward it to the corresponding client.

3. Implement the core code of cool chat function

With the implementation idea, it is easy to implement the function. Next, let us first take a look at the code in the hub ChatHub:

public class ChatHub : Hub
 {
 // 静态属性
 public static List<UserInfo> OnlineUsers = new List<UserInfo>(); // 在线用户列表
 
 /// <summary>
 /// 登录连线
 /// </summary>
 /// <param name="userId">用户Id</param>
 /// <param name="userName">用户名</param>
 public void Connect(string userId, string userName)
 {
  var connnectId = Context.ConnectionId;
 
  if (OnlineUsers.Count(x => x.ConnectionId == connnectId) == 0)
  {
  if (OnlineUsers.Any(x => x.UserId == userId))
  {
   var items = OnlineUsers.Where(x => x.UserId == userId).ToList();
   foreach (var item in items)
   {
   Clients.AllExcept(connnectId).onUserDisconnected(item.ConnectionId, item.UserName);
   }
   OnlineUsers.RemoveAll(x => x.UserId == userId);
  }
 
  //添加在线人员
  OnlineUsers.Add(new UserInfo
  {
   ConnectionId = connnectId,
   UserId = userId,
   UserName = userName,
   LastLoginTime = DateTime.Now
  });
  }
 
  // 所有客户端同步在线用户
  Clients.All.onConnected(connnectId, userName, OnlineUsers);
 }
 
 
 /// <summary>
 /// 发送私聊
 /// </summary>
 /// <param name="toUserId">接收方用户连接ID</param>
 /// <param name="message">内容</param>
 public void SendPrivateMessage(string toUserId, string message)
 {
  var fromUserId = Context.ConnectionId;
 
  var toUser = OnlineUsers.FirstOrDefault(x => x.ConnectionId == toUserId);
  var fromUser = OnlineUsers.FirstOrDefault(x => x.ConnectionId == fromUserId);
 
  if (toUser != null && fromUser != null)
  {
  // send to
  Clients.Client(toUserId).receivePrivateMessage(fromUserId, fromUser.UserName, message);
 
  // send to caller user
  // Clients.Caller.sendPrivateMessage(toUserId, fromUser.UserName, message);
  }
  else
  {
  //表示对方不在线
  Clients.Caller.absentSubscriber();
  }
 }
 
 /// <summary>
 /// 断线时调用
 /// </summary>
 /// <param name="stopCalled"></param>
 /// <returns></returns>
 public override Task OnDisconnected(bool stopCalled)
 {
  var user = OnlineUsers.FirstOrDefault(u => u.ConnectionId == Context.ConnectionId);
 
  // 判断用户是否存在,存在则删除
  if (user == null) return base.OnDisconnected(stopCalled);
 
  Clients.All.onUserDisconnected(user.ConnectionId, user.UserName); //调用客户端用户离线通知
  // 删除用户
  OnlineUsers.Remove(user);
 
 
  return base.OnDisconnected(stopCalled);
 }
 }

The above is The main implementation of the server, let’s take a look at the client’s implementation code:

<script type="text/javascript">
var systemHub = $.connection.chatHub;
/ 连接IM服务器成功
// 主要是更新在线用户
systemHub.client.onConnected = function (id, userName, allUsers) {
 var node = chatCore.node, myf = node.list.eq(0), str = &#39;&#39;, i = 0;
 myf.addClass(&#39;loading&#39;);
 onlinenum = allUsers.length;
 if (onlinenum > 0) {
 str += &#39;<li class="ChatCore_parentnode ChatCore_liston">&#39;
  + &#39;<h5 id="i-i-span-nbsp-class-ChatCore-parentname-在线用户-span-em-nbsp-class-ChatCore-nums-nbsp-nbsp-onlinenum-nbsp-nbsp-em"><i></i><span class="ChatCore_parentname">在线用户</span><em class="ChatCore_nums">(&#39; + onlinenum + &#39;)</em></h5>&#39;
  + &#39;<ul id="ChatCore_friend_list" class="ChatCore_chatlist">&#39;;
 for (; i < onlinenum; i++) {
  str += &#39;<li id="userid-&#39; + allUsers[i].UserID + &#39;" data-id="&#39; + allUsers[i].ConnectionId + &#39;" class="ChatCore_childnode" type="one"><img  class="ChatCore_oneface lazy"  src="/static/imghwm/default1.png"  data-src="/Content/Images/001.jpg?&#39; + allUsers[i].UserID + &#39;"    alt="Asp.net uses SignalR to implement cool end-to-end chat function" ><span class="ChatCore_onename">&#39; + allUsers[i].UserName + &#39;(&#39; + &#39;)</span><em class="ChatCore_time">&#39; + allUsers[i].LoginTime + &#39;</em></li>&#39;;
 }
 str += &#39;</ul></li>&#39;;
 myf.html(str);
 } else {
 myf.html(&#39;<li class="ChatCore_errormsg">没有任何数据</li>&#39;);
 }
 myf.removeClass(&#39;loading&#39;);
};
//消息传输
chatCore.transmit = function () {
var node = chatCore.node, log = {};
node.sendbtn = $(&#39;#ChatCore_sendbtn&#39;);
node.imwrite = $(&#39;#ChatCore_write&#39;);
 
//发送
log.send = function () {
 var data = {
 content: node.imwrite.val(),
 id: chatCore.nowchat.id,
 sign_key: &#39;&#39;, //密匙
 _: +new Date
 };
 
 if (data.content.replace(/\s/g, &#39;&#39;) === &#39;&#39;) {
 layer.tips(&#39;说点啥呗!&#39;, &#39;#ChatCore_write&#39;, 2);
 node.imwrite.focus();
 } else {
 //此处皆为模拟
 var keys = chatCore.nowchat.type + chatCore.nowchat.id;
 
 //聊天模版
 log.html = function (param, type) {
  return &#39;<li class="&#39; + (type === &#39;me&#39; ? &#39;ChatCore_chateme&#39; : &#39;&#39;) + &#39;">&#39;
  + &#39;<div class="ChatCore_chatuser">&#39;
   + function () {
   if (type === &#39;me&#39;) {
    return &#39;<span class="ChatCore_chattime">&#39; + param.time + &#39;</span>&#39;
     + &#39;<span class="ChatCore_chatname">&#39; + param.name + &#39;</span>&#39;
     + &#39;<img  src="/static/imghwm/default1.png"  data-src="&#39; + param.face + &#39;"  class="lazy"    alt="Asp.net uses SignalR to implement cool end-to-end chat function" >&#39;;
   } else {
    return &#39;<img  src="/static/imghwm/default1.png"  data-src="&#39; + param.face + &#39;"  class="lazy"    alt="Asp.net uses SignalR to implement cool end-to-end chat function" >&#39;
     + &#39;<span class="ChatCore_chatname">&#39; + param.name + &#39;</span>&#39;
     + &#39;<span class="ChatCore_chattime">&#39; + param.time + &#39;</span>&#39;;
   }
   }()
  + &#39;</div>&#39;
  + &#39;<div class="ChatCore_chatsay">&#39; + param.content + &#39;<em class="ChatCore_zero"></em></div>&#39;
  + &#39;</li>&#39;;
 };
 
 log.imarea = chatCore.chatbox.find(&#39;#ChatCore_area&#39; + keys);
 
 log.imarea.append(log.html({
  time: new Date().toLocaleString(),
  name: config.user.name,
  face: config.user.face,
  content: data.content
 }, &#39;me&#39;));
 node.imwrite.val(&#39;&#39;).focus();
 log.imarea.scrollTop(log.imarea[0].scrollHeight);
 
 // 调用服务端sendPrivateMessage方法来转发消息
 systemHub.server.sendPrivateMessage(chatCore.nowchat.id, data.content);
 }
 
};
node.sendbtn.on(&#39;click&#39;, log.send);
 
node.imwrite.keyup(function (e) {
 if (e.keyCode === 13) {
 log.send();
 }
});
};
 
//用户离线
systemHub.client.onUserDisconnected = function (id, userName) {
 onlinenum = onlinenum - 1;
 $(".ChatCore_nums").html("(" + onlinenum + ")");
 $("#ChatCore_friend_list li[data-id=" + id + "]").remove();
};
// 启动连接
$.connection.hub.start().done(function () {
 systemHub.server.connect(userid, username); // 调用服务端connect方法
});
</script>

The above only lists some core code implementations. In addition, in order to achieve cool effects, a Jquery plug-in is used here: layer, the official website is: http://layer.layui.com/. This plug-in is mainly used to achieve the effects of pop-up boxes and pop-up layers. To achieve cool chat effects, you need to write JS code yourself. Since I am not very familiar with the front-end, this JS special effects code is also based on the implementation on the Internet. If you want to run it and see the effect, it is recommended to download the source code at the end of the article and run it.

4. Final effect

After introducing the implementation ideas and implementation code, now that we have reached our exciting moment, that is to see if our implemented functions can meet the needs. In addition, in addition to meeting the basic chat functions, You also need to see if the interface is cool enough.

Asp.net uses SignalR to implement cool end-to-end chat function



For more related articles about Asp.net using SignalR to implement cool end-to-end chat functions, please pay attention to the PHP Chinese website!


Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
From Web to Desktop: The Versatility of C# .NETFrom Web to Desktop: The Versatility of C# .NETApr 15, 2025 am 12:07 AM

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C# .NET and the Future: Adapting to New TechnologiesC# .NET and the Future: Adapting to New TechnologiesApr 14, 2025 am 12:06 AM

C# and .NET adapt to the needs of emerging technologies through continuous updates and optimizations. 1) C# 9.0 and .NET5 introduce record type and performance optimization. 2) .NETCore enhances cloud native and containerized support. 3) ASP.NETCore integrates with modern web technologies. 4) ML.NET supports machine learning and artificial intelligence. 5) Asynchronous programming and best practices improve performance.

Is C# .NET Right for You? Evaluating its ApplicabilityIs C# .NET Right for You? Evaluating its ApplicabilityApr 13, 2025 am 12:03 AM

C#.NETissuitableforenterprise-levelapplicationswithintheMicrosoftecosystemduetoitsstrongtyping,richlibraries,androbustperformance.However,itmaynotbeidealforcross-platformdevelopmentorwhenrawspeediscritical,wherelanguageslikeRustorGomightbepreferable.

C# Code within .NET: Exploring the Programming ProcessC# Code within .NET: Exploring the Programming ProcessApr 12, 2025 am 12:02 AM

The programming process of C# in .NET includes the following steps: 1) writing C# code, 2) compiling into an intermediate language (IL), and 3) executing by the .NET runtime (CLR). The advantages of C# in .NET are its modern syntax, powerful type system and tight integration with the .NET framework, suitable for various development scenarios from desktop applications to web services.

C# .NET: Exploring Core Concepts and Programming FundamentalsC# .NET: Exploring Core Concepts and Programming FundamentalsApr 10, 2025 am 09:32 AM

C# is a modern, object-oriented programming language developed by Microsoft and as part of the .NET framework. 1.C# supports object-oriented programming (OOP), including encapsulation, inheritance and polymorphism. 2. Asynchronous programming in C# is implemented through async and await keywords to improve application responsiveness. 3. Use LINQ to process data collections concisely. 4. Common errors include null reference exceptions and index out-of-range exceptions. Debugging skills include using a debugger and exception handling. 5. Performance optimization includes using StringBuilder and avoiding unnecessary packing and unboxing.

Testing C# .NET Applications: Unit, Integration, and End-to-End TestingTesting C# .NET Applications: Unit, Integration, and End-to-End TestingApr 09, 2025 am 12:04 AM

Testing strategies for C#.NET applications include unit testing, integration testing, and end-to-end testing. 1. Unit testing ensures that the minimum unit of the code works independently, using the MSTest, NUnit or xUnit framework. 2. Integrated tests verify the functions of multiple units combined, commonly used simulated data and external services. 3. End-to-end testing simulates the user's complete operation process, and Selenium is usually used for automated testing.

Advanced C# .NET Tutorial: Ace Your Next Senior Developer InterviewAdvanced C# .NET Tutorial: Ace Your Next Senior Developer InterviewApr 08, 2025 am 12:06 AM

Interview with C# senior developer requires mastering core knowledge such as asynchronous programming, LINQ, and internal working principles of .NET frameworks. 1. Asynchronous programming simplifies operations through async and await to improve application responsiveness. 2.LINQ operates data in SQL style and pay attention to performance. 3. The CLR of the NET framework manages memory, and garbage collection needs to be used with caution.

C# .NET Interview Questions & Answers: Level Up Your ExpertiseC# .NET Interview Questions & Answers: Level Up Your ExpertiseApr 07, 2025 am 12:01 AM

C#.NET interview questions and answers include basic knowledge, core concepts, and advanced usage. 1) Basic knowledge: C# is an object-oriented language developed by Microsoft and is mainly used in the .NET framework. 2) Core concepts: Delegation and events allow dynamic binding methods, and LINQ provides powerful query functions. 3) Advanced usage: Asynchronous programming improves responsiveness, and expression trees are used for dynamic code construction.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools