首页 > 其他分享 >SignalR

SignalR

时间:2024-12-24 11:21:17浏览次数:4  
标签:string cid res await SignalR var id

参考地址

ASP.NET Core SignalR 入门 | Microsoft Learn

十四、Net Core6 SignalR 入门(二)发送消息给指定用户_netcore6 想后台数据库有增量了就向前台推送消息如何实现-CSDN博客

1.添加 SignalR 客户端库

2.创建 SignalR 中心

中心是一个类,用作处理客户端 - 服务器通信的高级管道。

在 SignalRChat 项目文件夹中,创建 Hubs 文件夹。

在 Hubs 文件夹中,使用以下代码创建 ChatHub 类:

public interface IChatClient
{
    Task ReceiveMessage(TransData data);
}
public class ChatHub : Hub<IChatClient>
{
  
    private readonly static Dictionary<string, string> _connections = new();
    private readonly string systemid = "system";
    private readonly string systemname = "system";
    /// <summary>
    /// 
    /// </summary>
    /// <param name="Id">连接ID</param>
    /// <param name="User">用户名</param>
    /// <param name="Message">消息</param>
    public record TransData(string Id, string User, string Message);

    #region SignalR用户
    /// <summary>
    /// 获取连接的唯一 ID(由 SignalR 分配)。 每个连接都有一个连接 ID
    /// </summary>
    /// <returns></returns>
    public string GetConnectionId()
    {
        var connectionId= Context.ConnectionId;
        return connectionId;
    }
    #endregion

    #region 发送消息
    /// <summary>
    /// 以个人名义向所有客户端发送消息
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendToAll(string message)
    {
        string cid = GetConnectionId();
        await Clients.All.ReceiveMessage(new(cid, _connections[cid], message));
    }

    /// <summary>
    /// 以系统名义向所有客户端发送消息
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendSysToAll(string message) => await Clients.All.ReceiveMessage(new(systemid, systemname, message));

    /// <summary>
    /// 发送消息给指定用户(个人)
    /// </summary>
    /// <param name="id"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendToOne(string id, string message)
    {
        string cid = GetConnectionId();
        await Clients.Client(id).ReceiveMessage(new(cid, _connections[cid], message));
    }

    /// <summary>
    /// 发送消息给指定用户(系统)
    /// </summary>
    /// <param name="id"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendSysToOne(string id, string message) => await Clients.Client(id).ReceiveMessage(new(systemid, systemname, message));

    /// <summary>
    /// 发送群组消息(个人)
    /// </summary>
    /// <param name="group"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendToGroup(string group, string message)
    {
        string cid = GetConnectionId();
        await Clients.Group(group).ReceiveMessage(new(cid, _connections[cid], message));
    }

    /// <summary>
    /// 发送群组消息(系统)
    /// </summary>
    /// <param name="group"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task SendSysToGroup(string group, string message) => await Clients.Group(group).ReceiveMessage(new(systemid, systemname, message));
    #endregion

    #region SignalR群组
    /// <summary>
    /// 主动加入群组
    /// </summary>
    /// <param name="group"></param>
    /// <returns></returns>
    public async Task AddToGroup(string group)
    {
        string cid = GetConnectionId();
        await Groups.AddToGroupAsync(cid, group);
        await SendSysToGroup(group, $@"欢迎{_connections[cid]}加入");
    }

    /// <summary>
    /// 被动加入群组
    /// </summary>
    /// <param name="group"></param>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task AddToGrouped(string group, string id)
    {
        string cid = GetConnectionId();
        await Groups.AddToGroupAsync(id, group);
        await SendSysToGroup(group, $@"欢迎{_connections[cid]}加入");
    }
    #endregion

    #region 临时用户操作
    /// <summary>
    /// 添加到在线用户集
    /// </summary>
    /// <param name="user"></param>
    /// <returns></returns>
    public async Task AddUser(string name)
    {
        string cid = GetConnectionId();
        if (!_connections.ContainsKey(cid))
        {
            await Task.Run(() => _connections.Add(cid, name));
            await SendSysToAll("relst");
        }
    }

    /// <summary>
    /// 获取在线用户
    /// </summary>
    /// <returns></returns>
    public object GetUser()
    {
        string cid = GetConnectionId();
        return _connections.Where(t => !t.Key.Equals(cid));
    }
    #endregion

    #region 重写连接断开钩子
    /// <summary>
    /// 重写链接钩子
    /// </summary>
    /// <returns></returns>
    public override async Task OnConnectedAsync()
    {
        await base.OnConnectedAsync();
    }

    /// <summary>
    /// 重写断开链接钩子
    /// </summary>
    /// <param name="exception"></param>
    /// <returns></returns>
    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        string cid = GetConnectionId();
        _connections.Remove(cid);
        await SendSysToAll("relst");
        await base.OnDisconnectedAsync(exception);
    }
    #endregion
}

3.配置 SignalR

 

4.添加 SignalR 客户端代码

"use strict";
var user = { id: '1', name: '111' };
var userlst = [];//用户列表
var msglst = [{ id: '', msg: [{}] }];//与用户的聊天记录
var nowuser = { id: 0, name: '123' };//当前聊天对象
var nowmsglst = [];//当前聊天记录
var nowmsg = "";

//1.创建
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//2.启动连接
start();

//如果关闭重新启动
connection.onclose(async () => {
  await start();
});

//3.接收消息
connection.on("ReceiveMessage", function (res) {
  console.log(res);
  switch (res.message) {
    case 'relst': //中心通知有新用户加入
      getUserLst();
      break;
    default: //默认接收消息处理
      //得到当前发送者的消息集位置
      let inx = msglst.findIndex(t => {
        return t.id == res.id
      });
      //如果不存在,则添加进消息集
      //否则在指定用户消息及添加消息
      if (inx == -1) {
        msglst.push({
          id: res.id,
          msg: [{
            id: res.id,
            msg: res.message
          }]
        })
      } else {
        msglst[inx].msg.push({
          id: res.id,
          msg: res.message
        })
      }
      //消息加1
      editState(res.id, true);
      //如果为当前聊天用户,赋值并自动滑到底部
      if (nowuser.id == res.id) {
        nowmsglst.push({
          id: res.id,
          msg: res.message
        })
        editState(res.id, false);
      };

      break;
  }
  var li = document.createElement("li");
  document.getElementById("messagesList").appendChild(li);
  // We can assign user-supplied strings to an element's textContent because it
  // is not interpreted as markup. If you're assigning in any other way, you 
  // should be aware of possible script injection concerns.
  //li.textContent = `${user} says ${message}`;
});

document.getElementById("sendButton").addEventListener("click", function (event) {
  nowmsg = document.getElementById("messageInput").value;
  //4.发送消息
  sendmsg();
  event.preventDefault();
});

//连接方法,如果连接失败,5s后重新连接
async function start() {
  try {
    await connection.start();
    user.name = getName(); //得到当前用户名
    user.id = await getmyid(); //得到当前用户ID
    login(); //主动加入到用户列表
    console.log("连接成功.");
  } catch (err) {
    console.log(err);
    setTimeout(start, 5000);
  }
}

//跳转
async function trun(d) {
  //if (d) {
  //  this.nowuser = d;
  //  this.editState(d.id, false);
  //}
  //this.showbox = !this.showbox;
  let res = await msglst.findIndex(t => {
    return t.id == nowuser.id
  });
  if (res >= 0) {
    nowmsglst = msglst[res].msg;
  } else {
    nowmsglst = [{
      id: '',
      msg: ''
    }];
  }
}

function login() {
  connection.invoke("AddUser", user.name);
}

//获取在线用户列表
function getUserLst() {
  connection.invoke("GetUser").then(res => {
    createlst(res);
  });
}

//获取个人ID
function getmyid() {
  return new Promise(function (resolve, reject) {
    connection.invoke("GetConnectionId").then(res => {
      resolve(res);
      return res;
    });
  })

}

//发送消息
async function sendmsg() {
  nowuser = userlst[0];
  connection.send("SendToOne", nowuser.id, nowmsg)
  var obj = {
    id: user.id,
    msg: nowmsg
  };
  nowmsglst.push(obj);
  let res = await msglst.findIndex(t => {
    return t.id == nowuser.id
  });
  if (res == -1) {
    msglst.push({
      id: nowuser.id,
      msg: nowmsglst
    })
  } else {
    msglst[res].msg = nowmsglst
  }
  //scrollTop();
  nowmsg = '';
}

//重构上线用户列表
function createlst(lst) {
  userlst = [];
  for (var d in lst) {
    userlst.push({
      id: lst[d].key,
      name: lst[d].value,
      state: 0
    })
  }
}
//指定用户清空消息
async function editState(cid, isadd) {
  let inx = await userlst.findIndex(t => {
    return t.id == cid
  });
  if (isadd) {
    userlst[inx].state = Number(userlst[inx].state) + 1;
  } else {
    userlst[inx].state = 0;
  }
}

function getName() {
  var familyNames = new Array(
    "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈",
    "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许",
    "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏",
    "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章",
    "云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦",
    "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳",
    "酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺",
    "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常",
    "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余",
    "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹"
  );
  var givenNames = new Array(
    "子璇", "淼", "国栋", "夫子", "瑞堂", "甜", "敏", "尚", "国贤", "贺祥", "晨涛",
    "昊轩", "易轩", "益辰", "益帆", "益冉", "瑾春", "瑾昆", "春齐", "杨", "文昊",
    "东东", "雄霖", "浩晨", "熙涵", "溶溶", "冰枫", "欣欣", "宜豪", "欣慧", "建政",
    "美欣", "淑慧", "文轩", "文杰", "欣源", "忠林", "榕润", "欣汝", "慧嘉", "新建",
    "建林", "亦菲", "林", "冰洁", "佳欣", "涵涵", "禹辰", "淳美", "泽惠", "伟洋",
    "涵越", "润丽", "翔", "淑华", "晶莹", "凌晶", "苒溪", "雨涵", "嘉怡", "佳毅",
    "子辰", "佳琪", "紫轩", "瑞辰", "昕蕊", "萌", "明远", "欣宜", "泽远", "欣怡",
    "佳怡", "佳惠", "晨茜", "晨璐", "运昊", "汝鑫", "淑君", "晶滢", "润莎", "榕汕",
    "佳钰", "佳玉", "晓庆", "一鸣", "语晨", "添池", "添昊", "雨泽", "雅晗", "雅涵",
    "清妍", "诗悦", "嘉乐", "晨涵", "天赫", "?傲", "佳昊", "天昊", "萌萌", "若萌"
  );

  var i = parseInt(10 * Math.random()) * 10 + parseInt(10 * Math.random());
  var familyName = familyNames[i];

  var j = parseInt(10 * Math.random()) * 10 + parseInt(10 * Math.random());
  var givenName = givenNames[i];

  var name = familyName + givenName;
  return name;
}

 

标签:string,cid,res,await,SignalR,var,id
From: https://www.cnblogs.com/xm123/p/18626973

相关文章

  • C#使用SignalR实现与前端vue实时通信
    C#后端1、安装SignalR包首先确保项目中已安装SignalR相关包。可以通过NuGet包管理器安装:dotnetaddpackageMicrosoft.AspNetCore.SignalR2、配置SignalR在Startup.cs文件中配置SignalRusingMicrosoft.AspNetCore.Builder;usingMicrosoft.AspNetCore.Hosting;......
  • SignalR实时消息推送
    后端创建一个Hub类,重写连接和断连方法ChatHub记录下每一位登录人连接SignalR的信息至Redis中引用的Microsoft.AspNetCore.App框架publicclassChatHub:Hub{//ConcurrentDictionary<string,HubUser>concurrentDictionary=newConcurrentDictionary<string,HubU......
  • Abp vNext+SignalR
    我的项目基于ABPvNext(版本8.2.0)+Blazor+SQLServer。从官网下载的模板默认不包含SignalR,因此这里记录了如何在ABPvNext中集成SignalR实现实时通信的过程。以下是一个详细的集成步骤指南:1.安装所需的NuGet包官方文档:https://abp.io/docs/latest/framework/rea......
  • Asp.net core SignalR + Vue
    简介:ASP.NETSignalR是一个ASP.NET下的类库,可以在ASP.NET的Web项目中实现实时通信。本文主要讲述如何在Vue.js中使用SignalR,以及断开重连。知识点:前端SignalR的安装如何设置自动重新连接的次数SignalR有关连接的函数自动重连全部失败后,定时重连ASP.NETCORESig......
  • SignalR服务端嵌入到WPF
    用的是.netframework4.7.2的WPF。<Windowx:Class="EBServerTry.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:......
  • 第五十节:Core8.0中的新变化(SignalR写法、本机AOT发布)
    一.新变化 详见:https://learn.microsoft.com/zh-cn/aspnet/core/release-notes/aspnetcore-8.0?view=aspnetcore-8.0如下图: 二. SignalR改变JS中在ASP.NETCore7.0或更早版本中默认值的两倍值的分配varconnection=newsignalR.HubConnectionBuilder().withU......
  • Microsoft.AspNetCore.SignalR.Client中传送用户Token
    Microsoft.AspNetCore.SignalR.Client的.Net客户端传送Token的最佳方法!如下将Authorization标头添加到HubConnectionBuilder中,如下所示:对于不记名令牌->HubConnection=newHubConnectionBuilder().WithUrl($"https://10.0.2.2:5001/chatHub",(opts)=>......
  • Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室
    SignalR牛刀小试在MVP杨老师的博客里看到这么个东西,我还以为是NetCore3才推出的新玩意,原来是已经有很多年的历史了,那看来还是比较成熟的一个技术了。简介SignalR是一个.NETCore/.NETFramework的开源实时框架,SignalR的可使用WebSocket,ServerSentEvents和LongPolling......
  • netcore webpi 通过signalr 给vue项目推送消息
     最近项目上需要做个服务给前端推消息,首先就想到了signalr,关于signalr详情可以参考微软官方文档(ASP.NETCoreSignalR概述|MicrosoftLearn),微软现在也有使用教程(ASP.NETCoreSignalR入门|MicrosoftLearn)微软教程是通过使用库管理器(LibMan)从unpkg 获取客户端库,如......
  • 升讯威在线客服系统的并发高性能数据处理技术:超强的 SignalR
    我在业余时间开发维护了一款免费开源的升讯威在线客服系统,也收获了许多用户。对我来说,只要能获得用户的认可,就是我最大的动力。最近客服系统成功经受住了客户现场组织的压力测试,获得了客户的认可。客户组织多名客服上线后,所有员工同一时间打开访客页面疯狂不停的给在线客服发消......