草庐IT

(附源码)vue3.0+.NET6实现聊天室(实时聊天SignalR)

ARW 阿尔文科技 2025-07-18 原文

参考文章

搭建文章


gitte源码

在线体验

可以注册两个号来测试

演示图:

一. 整体介绍

  介绍SignalR一种通讯模型Hub(中心模型,或者叫集线器模型),调用这个模型写好的方法,去发送消息。

  内容有:

    ①:Hub模型的方法介绍

    ②:服务器端代码介绍

    ③:前端vue3 安装并调用后端方法

    ④:聊天室样例

整体流程:

1、进入网站 -> 调用连接 SignalR 的方法

2、与好友发送消息 -> 调用 SignalR 的自定义方法

 

前端通过,signalR内置方法 .invoke()  去请求接口

3、监听接受方法(渲染消息)

通过 new signalR.HubConnectionBuilder().on("接受方法") 这个函数

然后将接受的消息 存放到数组里 

 再 v-for 将数据渲染出来

4、退出浏览器或退出登录,触发 “连接终止时调用” (OnDisconnectedAsync)

修改登录状态为 离线

        /// <summary>
        /// 连接终止时调用。
        /// </summary>
        /// <returns></returns>
        public override Task OnDisconnectedAsync(Exception? exception)
        {
            var httpContext = Context.GetHttpContext();
            var username = httpContext.Request.Cookies["username"];

            if (username == null)
            {
                throw new Exception("系统异常连接失败");
            }

            // 修改用户登录状态
            _ChatLoginService.Update(s => s.ChatUserName == username,
               f => new ChatUser
               {
                   Status = 0
               });

            var user = clientusers.Where(p => p.ConnectionId == Context.ConnectionId).FirstOrDefault();
            判断用户是否存在,否则添加集合
            if (user != null)
            {
                clientusers.Remove(user);
            }
            return base.OnDisconnectedAsync(exception);
        }

在文件夹 ARW-vue-main\src\views\tool\chat 中的 index.vue 是简易版的demo

可以先把这个搞明白,后面会很好理解

这个对应的Hub 是 MessageHub 

二. Hub模型的方法介绍

继承成Hub类,所以可以Override三个方法:

  (1). OnConnected:连接成功时调用

  (2). OnDisconnected:连接断开时调用

  (3). OnReconnected:重连时调用

我这里用于 修改用户登录状态 在线人数列表...


使用Clients对象进行调用,Clients对象下的属性和方法有:

(1). 向指定人发送,一对一:Client(string connectionId)

(2). 向某个组发送:Group(roomName)

(3). 进入某个房间:Group.AddToGroupAsync(connectId, roomName)

三. 服务器端代码介绍

        好友聊天思路详细讲解:

        /// <summary>
        /// 好友发送信息
        /// </summary>
        /// <param name="user"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendFriendsChat(string selfConnectionId, string connectId, string sender, string receiver, string message)
        {
            if (string.IsNullOrEmpty(connectId))
            {
                throw new CustomException("好友不在线,请留言!");
            }

            // 服务端主动调用客户端的方法
            // 向指定用户(connectId)发送指定消息
            // 监听接受方法("ReceiveMessage")来获取消息 -> ( new { sender, receiver, message } )
            await Clients.Client(connectId).SendAsync("ReceiveMessage", new { sender, receiver, message });
            await Clients.Client(selfConnectionId).SendAsync("ReceiveMessage", new { sender, receiver, message });
        }

我们直接手撕源码,先看这个方法的参数 一共有5个

参数说明: connectId-> 在连接SignalR时会给该用户生成一个连接Id,并存在在线用户列表

后面统称 "连接ID"

1、selfConnectionId -> 自己的连接ID

2、connectId -> 对方的连接ID

3、sender -> 发送者的用户GUID

4、receiver-> 接收者的用户GUID

5、message -> 发送的消息

首先我们给发送消息,必须先知道对方的 connectId

才能够调用 Clients.Client(connectId).SendAsync(.......)

Q:为什么需要自己的连接ID呢?

A:因为给对方发送,对方能够接收到消息,但自己是接收不到的,所以这里要给自己也发一份。因而需要传自己的连接ID。

Q:如何区分是谁发送的消息?

A:这里我用的是 接收者 和 发送者 做的判断,这里需要捋一捋思路,所以这里要传发送者的GuId 和 接收者的GuId。(发送消息时也带 sender 和 recevier)

 下图是我在渲染聊天列表时做的判断:

Q:如果好友不在线,获取不到对方的连接ID怎么办?

A:这个情况再去请求Hub接口是会报错的,因为对方的连接Id是空的。我的做法是每次发送一条消息就会存进数据库里嘛,然后判断一下对方是否在线,不在线就获取他们之间的对话的最新一条消息,这里sql比较复杂,感兴趣的可以看看这个

看懂这个方法后,来看一下 前端调用

基础使用

对前端感兴趣的可以看一下源码

        群聊聊天思路详解:

        /// <summary>
        /// 进入指定组
        /// </summary>
        /// <param name="connectId"></param>
        /// <param name="roomName">组的名称</param>
        [HubMethodName(nameof(EnterRoom))]
        public void EnterRoom(string connectId, string roomName)
        {
            Groups.AddToGroupAsync(connectId, roomName);
        }

        /// <summary>
        /// 群聊天(发送信息)
        /// </summary>
        /// <param name="roomName"></param>
        public async Task SendGroupChat(string roomName, string groupGuId, string selfConnectionId, string senderId, string receiver, string message)
        {
            var guid = senderId.ParseToLong();
            var groupguid = groupGuId.ParseToLong();
            var sender = _ChatLoginService.FindUserByGuid(guid).Result;

            await Clients.Group(roomName)
                .SendAsync("groupMessages", new { roomName, sender, receiver, message });

            _GroupUserService.Update(s => s.GroupGuId == groupguid,
            f => new GroupUser
            {
                IsRead = false
            });

            //await Clients.Client(selfConnectionId).SendAsync("groupMessages", new { sender, receiver, message });
        }

    }

我们继续手撕源码,先看这个方法的参数 一共有6

参数说明: roomName -> 在SignalR中组名,如果没有这个组名则添加并进入列表,有则加入组

后面统称 "组"

1、roomName -> 组名

2、groupGuId -> 群聊的GUID

3、selfConnectionId -> 自己的连接ID

4、senderId -> 发送者的用户GUID

5、receiver-> 接收者的GUID(这里指群聊的GUID)

6、message -> 发送的消息

Clients.Group(roomName).SendAsync("接受方法名",发送的消息)

首先要 进入到房间内:

把自己的连接ID放进去,以及群聊名称

Groups.AddToGroupAsync(connectId, roomName);

在群聊发送消息,需要做到:

1、通过 roomName 发送消息到这个房间

2、通过 groupGuId 来修改用户是否已读

3、通过 senderId 来判断是否自己发的,不是则展示群成员发的头像和所发的消息

4、通过 receiver 来判断这个群聊是否为指定的群

有关(附源码)vue3.0+.NET6实现聊天室(实时聊天SignalR)的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

随机推荐