话不多说,上代码

1、首先nuget引用Microsoft.AspNetCore.SignalR包

2、在Startup文件ConfigureServices加入services.AddSignalR();和跨域的代码,如下:

public IServiceProvider ConfigureServices(IServiceCollection services){//消息推送services.AddSignalR();//跨域 发布正式环境需要设置访问主机限制services.AddCors(options =>{options.AddPolicy("CorsPolicy", builder =>{builder.SetIsOriginAllowed(origin => true).AllowAnyHeader().AllowAnyMethod().AllowCredentials();});});.........}

3、Configure里面(一个跨域和一个路由):

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}//跨域app.UseCors("CorsPolicy");//添加SignalR路由配置代码,路由指向自定义类MessageHubapp.UseSignalR(routes => {routes.MapHub<MessageHub>("/MessageHub");//直接路由到下面消息处理类});。。。。。}

4、建立一个消息处理类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CriticalMass.C2C.Model;
using Microsoft.AspNetCore.SignalR;
namespace CriticalMass.C2C.API.Extend
{[AllowCrossSiteJson]public class MessageHub:Hub{public static List<ConnectionSession> UserList = new List<ConnectionSession> { };//发送消息--发送给所有连接的客户端public Task SendMessage(string msg){return Clients.All.SendAsync("ReceiveMessage", msg);}//发送消息--发送给指定用户public Task SendPrivateMessage(string connectionId, string message){return Clients.Client(connectionId).SendAsync("ReceiveMessage", message);}/// <summary>/// 客户端登录到服务器/// </summary>/// <param name="uid"></param>public Task SendLogin(int uid) {AjaxResult result = new AjaxResult();try{ConnectionSession cs = UserList.Find(a => a.Uid == uid);if (cs != null){UserList.Remove(cs);}UserList.Add(new ConnectionSession{Uid = uid,ConnectionId = Context.ConnectionId});result.Msg = "ok";}catch (Exception ex) {result.Msg = ex.Message;}return Clients.Client(UserList.Find(a=>a.Uid==uid).ConnectionId).SendAsync("ReceiveLogin", result.ToJson());}}public class ConnectionSession { public int Uid { get; set; }public string ConnectionId { get; set; }}
}

5、前端代码

<ul class="form-group" id="messagesListUl" style="margin-bottom:20px"></ul><ul class="form-group" id="messagesListUl2" style="margin-bottom:20px"></ul><div class="form-group"><label for="username">姓名:</label><input type="text" class="form-control" id="username" name="username"></div><div class="form-group"><label for="msgcontent">内容:</label><textarea rows="5" cols="20" id="msgcontent" name="msgcontent" class="form-control"></textarea></div><input type="button" οnclick="btnSendMsg()" value="发送"><script src="jquery.js"></script>
<script src="signalr.js"></script>
<script type="text/javascript">//创建连接对象connectionconst signalr_connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:65423/MessageHub")//这里是我们前面建的那个类的名字.configureLogging(signalR.LogLevel.Information).build();//启动connectionsignalr_connection.start().then(function(){console.log("连接成功");//这里与服务器连接成功之后,就要执行登录signalr_connection.invoke("SendLogin", 18/*我这里传入的是用户ID,登录服务器之后需要保存用户信息的*/).catch(err => console.error("发送失败:"+err.toString()));}).catch(function(ex){console.log("连接失败"+ex);//SignalR JavaScript 客户端不会自动重新连接,必须编写代码将手动重新连接你的客户端//setTimeout(() => start(), 5000);});async function start() {try {await signalr_connection.start();console.log("connected");} catch (err) {console.log(err);setTimeout(() => start(), 5000);}};signalr_connection.onclose(async () => {start();});signalr_connection.on("ReceiveChartMessage", function(data) {var msgObj = JSON.parse(data);//json串转对象console.log(JSON.stringify(msgObj));const li = document.createElement("li");li.textContent=JSON.stringify(msgObj);document.getElementById("messagesListUl2").appendChild(li);});//绑定事件("ReceiveMessage"和服务器端的SendMessage方法中的第一个参数一致)signalr_connection.on("ReceiveMessage", function(data) {var msgObj = JSON.parse(data);//json串转对象const li = document.createElement("li");li.textContent = msgObj.name + " : " + msgObj.message;document.getElementById("messagesListUl").appendChild(li);});//接受登录成功的消息signalr_connection.on("ReceiveLogin", function(data) {var msgObj = JSON.parse(data);//json串转对象console.log(JSON.stringify(msgObj));if(msgObj.Msg=="ok"){alert("登录成功");}else{alert(msgObj.Msg);}});//发送消息function btnSendMsg(){var username = $.trim($("#username").val());var msgcontent = $.trim($("#msgcontent").val());var msgObj={};msgObj.name=username;msgObj.message=msgcontent;var jsonstr=JSON.stringify(msgObj);//对象转json串console.log(jsonstr);signalr_connection.invoke("SendMessage", jsonstr).catch(err => console.error("发送失败:"+err.toString()));}
</script>

说两个方法:

signalr_connection.invoke调用后台服务
signalr_connection.on 前端页面监听后台方法调用
这个前端跟后台之间的相互调用有点蛋疼,耐着性子多看几遍就会明白,他娘的就跟RPC一样6、后台消息推送实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using CriticalMass.C2C.Model;
using CriticalMass.C2C.IRepository;
using CriticalMass.C2C.Utility;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Memory;
using CriticalMass.C2C.API.Extend;
using Microsoft.AspNetCore.SignalR;namespace CriticalMass.C2C.API.Controllers
{[TokenCheck]public class AdmChartController : BaseController{private readonly IHubContext<MessageHub> myHub;//构造函数注入MessageHubpublic AdmChartController(IHubContext<MessageHub> _myHub) {myHub = _myHub;}public string AuditChart([FromBody] dynamic parameModel) {AjaxResult result = new AjaxResult();try{string Ids = parameModel.ids;var ChartSrv = HttpContext.RequestServices.GetService<Itproduct_chart_detailsRepository>();var SessionSrv = HttpContext.RequestServices.GetService<Itproduct_chat_sessionRepository>();List<Model.tproduct_chart_details> lt = ChartSrv.GetList($"id in({Ids})");List<int> lt_status = lt.Map(a => (int)a.status).Distinct().ToList<int>();if (lt_status.Count > 1 || lt_status[0] != 0){throw new Exception("状态不正确.");}ChartSrv.Update("status=1", $"id in({Ids})");List<dynamic> lt_msg = new List<dynamic>();Ids.Split(',').Each(a=> {int uid = 0;int to_uid = 0;Model.tproduct_chart_details d = ChartSrv.GetModel(a.ToInt32());Model.tproduct_chat_session s = SessionSrv.GetModel((int)d.session_id);uid = (int)d.uid;if (uid == s.session_call){to_uid = (int)s.session_listen;}else {to_uid = (int)s.session_call;}var obj = new { session_id=s.id,uid= uid,to_uid= to_uid,msg=d.msg};lt_msg.Add(obj);});List<dynamic> list=lt_msg.Map(a => a.to_uid).Distinct().Map(b=> {return new {to_uid = b,sessions = lt_msg.Filter(c=>c.to_uid == b).Map(f=>f.session_id).Distinct().Map(g=> {return new {session_id=g,msg_lt= lt_msg.Filter(h=>h.to_uid==b && h.session_id==g).Map(j=> {return new {uid_send=j.uid,msg=j.msg};})};})};}).ToList<dynamic>();SendMsg(list);result.Msg = "ok";}catch (Exception ex) {result.Msg = ex.Message;}return result.ToJson();}/// <summary>/// 向客户端推送及时消息/// </summary>/// <param name="uid"></param>/// <param name="to_uid"></param>/// <param name="json"></param>public async Task SendMsg(List<dynamic> lt) {var task = Task.Run(()=> {lt.Each(a => {int to_uid = a.to_uid;object obj = a.sessions;try{ConnectionSession cs = MessageHub.UserList.Find(a => a.Uid == to_uid);//在线if (cs != null){myHub.Clients.Client(cs.ConnectionId).SendAsync("ReceiveChartMessage", obj.ToJson());}}catch { }});});await task;}}
}

注意

ConnectionSession cs = MessageHub.UserList.Find(a => a.Uid == to_uid);这一句

在MessageHub类定义了一个UserList用户信息全局静态数组变量,用户登陆后就会把用户信息更新到这个数据组

MessageHub.UserList.Find(a => a.Uid == to_uid)

这里我是通过用户ID在数组找到用户信息的,然后就可以拿到ConnectionId,拿到ConnectionId之后就可以给客户端发送通知了,发送pong到客户端ReceiveChartMessage这个方法(前面js中客户端已经对这个方法监听了),并带上参数即可

7、在线聊天原理差不多,服务器充当转发器即可

ASP.NET CORE SIGNALR消息推送及在线聊天相关推荐

  1. 基于websocket的网页实时消息推送与在线聊天(上篇)

    文章目录 @[toc] 基于websocket的网页实时消息推送与在线聊天(上篇) "使用dwebsocket在django中实现websocket" websocket原理图 d ...

  2. ASP.NET Core SignalR实时推送配置,业务层实时推送SignalR消息

    web框架版本:.NET 6 不需要安装nuget有关signalr的包 微软参考文档: https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/ ...

  3. Springboot集成websocket实现消息推送和在线用户统计

    一.HTTP 说到websocket首先要说Http,Http大家都知道是一个网络通信协议,每当客户端浏览器需要访问后台时都会发一个请求,服务器给出响应后该连接就会关闭,请求只能有客户端发起,服务端是 ...

  4. uni-app如何使用Unipush实现消息推送(在线离线)

    一.前期准备 在动手之前建议先看下官方文档:https://ask.dcloud.net.cn/article/id-35622__page-5 首先,在App模块配置勾选如下后,点击配置进入DClo ...

  5. swoole 点对点发送消息推送

    swoole+webSocket  消息推送,或则聊天室,实现. 先上代码,(上菜....)点对点,简单(客户发送,服务回复.) 点对所有,广播 见图所示:参数详解 /*** 1.实例化 对象* $h ...

  6. Asp.net SignalR 实现服务端消息推送到Web端

    参考博客https://www.cnblogs.com/wintersun/p/4148223.html ASP .NET SignalR是一个ASP .NET 下的类库,可以在ASP .NET 的W ...

  7. AngularJS+ASP.NET MVC+SignalR实现消息推送

    AngularJS+ASP.NET MVC+SignalR实现消息推送 原文:AngularJS+ASP.NET MVC+SignalR实现消息推送 背景 OA管理系统中,员工提交申请单,消息实时通知 ...

  8. NetCore + SignalR 实现日志消息推送

    哈喽大家周一好呀,感觉好久没有写文章了,上周出差了一次,感觉还是比坐办公室好的多,平时在读一本书<时生>,感兴趣的可以看看?...... 这几天翻看 NetCore 相关知识扩展的时候,发 ...

  9. SignalR服务器端消息推送

    目录 一.什么是SignalR 二.SignalR基本使用 三.单台服务器协商协议 四.多台服务器协商协议 五.SignalR分布式部署 六.SignalR身份认证 七.部分客户端的消息推送(私聊功能 ...

最新文章

  1. 【以太坊】javascript控制台完整交易流程
  2. Easyui入门视频教程 第01集---认识Easyui
  3. 群集lvs—DR的配置及应用
  4. ITK:将网格写入vtp文件
  5. shiro---注解
  6. 基于plotly数据可视化_[Plotly + Datashader]可视化大型地理空间数据集
  7. php 商品展示html,HTML5和CSS3实现3D展示商品信息的代码
  8. Spring框架注入注解与拦截器浅谈
  9. 对比,还原真实的GPU池化
  10. sql server使用维护计划定时备份完整数据库、差异数据库
  11. 送给程序员们的经典电子书大礼包
  12. mysql存储过程中的异常处理
  13. tftp java_TFTP服务器搭建
  14. 禁忌搜索(Tabu Search)算法及matlab实现(非旅行商(TSP)例子)
  15. 51单片机学习笔记——AD转换
  16. linux桌面只运行浏览器,分享|4 个 Linux 桌面上的轻量级图像浏览器
  17. recon-ng详细使用教程
  18. 常用的excel公式备忘
  19. Android加载GIF图片的两种方式
  20. 弱电包含在计算机专业,弱电工程包含哪些内容

热门文章

  1. 通过.NET反射动态调用SetValue方法给属性PropertyInfo动态类型赋值
  2. eclipse building workspace 卡住
  3. 帮我用python写一个春节烟花的代码
  4. c#——Winform PropertyGrid使用
  5. 几行样式代码,让你的网站全站和图片都变成灰色|CSS样式灰色代码
  6. windows update更新返回错误码统计(WUSA.exe)
  7. H3C交换机配置文件用FTP方法备份和恢复 使用SecureCRT,SecureFX
  8. Citrix相关资料及相关软件下载
  9. 【经典题目】rand7()生成rand10()——随机数算法
  10. html隔离样式,html – 如何将div与公共CSS样式隔离?