1,首先引入signalr,nuget中搜索安装就好,这里不多介绍,Microsoft.AspNetCore.SignalR.Common,不压缩的话就这个包就好
2,startup配置,ConfigureServices中
services.AddSignalR().AddMessagePackProtocol();
Configure中,为了给前端signalr请求加上token,token的定义可能不一样,你们自己定义
app.Use((context, next) =>
{
if (context.Request.Query.TryGetValue("Bearer", out var token))
context.Request.Headers.Add("Authorization", $"Bearer {token}");
return next.Invoke();
});
3,创建ChatHub类,继承Hub,注意要加上 [Authorize]验证特性
namespace AntAdmnin.Hubs
{
[Authorize]
public class ChatHub: Hub
{
//发送消息--发送给所有连接的客户端
//public async Task SendMessage(string msg)
//{
// await Clients.All.SendAsync("ReceiveMessage", msg);
//}
////发送消息--发送给指定用户
//public async Task SendPrivateMessage(string userId, string message)
//{
// await Clients.User(userId).SendAsync("ReceiveMessage", message);
//}
public override async Task OnConnectedAsync()
{
//await Clients.All.OnNotify(new { UserId= Context.User.Identity.Name, Name=Context.User.Identity.Name, ConnectId = Context.ConnectionId });
var userId = Context.User.Identity.Name;
//把上线的用户跟signalr connectionid保存起来
SignalrHelper.UserAndSignalrDc[userId] =Context.ConnectionId;
// 思路 创建一个组时 ,把用户的connectionid跟组名添加进signalr ,如果是持久性保存的组,可初始化时执行一遍组保存
// 例如这里把所有的用户添加到一个叫 company的组 ,要先初始化用户关联字典
foreach (var item in SignalrHelper.UserAndSignalrDc)
{
Groups.AddToGroupAsync(item.Value, "company");
}
await base.OnConnectedAsync();
}
}
}
4,创建一个字典,用来保存用户跟signalr连接id的关联,这应该是第三步才对,在上面signalr连接的时候保存数据
public class SignalrHelper
{
///
/// key是用户Id ,value 是connectionid
///
public static Dictionary UserAndSignalrDc = new Dictionary();
}
5,创建一个api控制器,ChatController,我这里用了autofac注入,不用的自己实例化就好,也可以不用控制器,直接请求chathub也是可以的
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
public class ChatController : ControllerBase
{
private IHubContext chatHub;
public ChatController(IHubContext chatHub)
{
this.chatHub = chatHub;
}
[HttpPost]
public async Task SendAllMsg(ChatRecordInput input)
{
try
{
chatHub.Clients.Group(input.Receiver.ToString()).SendAsync("ReceiveMessage", input.Msg);
await chatHub.Clients.All.SendAsync("ReceiveMessage", input.Msg);
return Ok(Result.Success());
}
catch (Exception ex)
{
throw ex;
}
}
[HttpPost]
public async Task SendGroupMsg(ChatRecordInput input)
{
try
{
await chatHub.Clients.Group("company").SendAsync("ReceiveMessage", input.Msg);
return Ok(Result.Success());
}
catch (Exception ex)
{
throw ex;
}
}
[HttpPost]
public async Task SendUserMsg(ChatRecordInput input)
{
try
{
var connectionId = SignalrHelper.UserAndSignalrDc[input.Receiver.ToString()];
await chatHub.Clients.Clients(connectionId).SendAsync("ReceiveMessage", input.Msg);
return Ok(Result.Success());
}
catch (Exception ex)
{
throw ex;
}
}
后端就是这样了,接下来是前端,用的vue
7, 同样先安装包 ,我这里用的yarn,npm的安装方式我试过好像安装不上的,不知道为什么,安装这个包花了很久,各种安装不上,知道的大佬说一下怎么回事
yarn add @aspnet/signalr
8,页面,ui我用的是ant, 大家可以只参考js部分,前后端的接收方法名得保持一致,这个应该都知道吧
{{ item.nickName }}
{{ remsg }}
发送信息