本文不对小程序与signalr做任何介绍,默认读者已经掌握
aspnetcore Signalr文档
小程序文档
SignalR没有提供小程序使用的客户端js,所以本人参考signlar.js写了小程序版signalr-client.js 代码开源,地址 https://github.com/liangshiw/SignalRMiniProgram-Client
先上效果图
Install-Package Microsoft.AspNetCore.SignalR
现在就可以创建hub集线器了,首先定义一个类来描述已在线的用户,它需要头像和姓名
public class OnlineClient { public string NickName { get; set; } public string Avatar { get; set; } }
接下来我们在连接创建时,把当前用户做为在线用户添加到字典中,向该用户发送加入成功的系统消息。并且同时向其他的用户发送系统消息
public override async Task OnConnectedAsync() { var http = Context.GetHttpContext(); var client = new OnlineClient() { NickName = http.Request.Query["nickName"], Avatar = http.Request.Query["avatar"] }; lock (SyncObj) { OnlineClients[Context.ConnectionId] = client; } await base.OnConnectedAsync(); await Groups.AddToGroupAsync(Context.ConnectionId, ChatName); await Clients.GroupExcept(ChatName, new[] { Context.ConnectionId }).SendAsync("system", $"用户{client.NickName}加入了群聊"); await Clients.Client(Context.ConnectionId).SendAsync("system", $"成功加入{ChatName}"); }
同样在用户断开连接时做离线处理
public override async Task OnDisconnectedAsync(Exception exception) { await base.OnDisconnectedAsync(exception); bool isRemoved; OnlineClient client; lock (SyncObj) { isRemoved = OnlineClients.TryRemove(Context.ConnectionId, out client); } await Groups.RemoveFromGroupAsync(Context.ConnectionId, ChatName); if (isRemoved) { await Clients.GroupExcept(ChatName, new[] { Context.ConnectionId }).SendAsync("system", $"用户{client.NickName}退出了群聊"); } }
下面就只有一个简单的发送消息方法了,首先查看当前用户是否在线并做相应处理,如果在线就把当前用户的消息和头像姓名一起发送给组中的其他客户端
public async Task SendMessage(string msg) { var client = OnlineClients.Where(x => x.Key == Context.ConnectionId).Select(x=>x.Value).FirstOrDefault(); if (client == null) { await Clients.Client(Context.ConnectionId).SendAsync("system", "您已不在聊天室,请重新加入"); } else { await Clients.GroupExcept(ChatName, new[] { Context.ConnectionId }).SendAsync("receive", new { msg, nickName = client.NickName, avatar = client.Avatar }); } }
在小程序中,我们需要在页面加载事件中创建与signalr的连接,并且注册system系统消息与receive用户消息两个方法以接收服务端发来的消息
onLoad: function (options) { this.hubConnect = new Hub.HubConnection(); this.hubConnect.start("https://chat.jingshonline.net/chat", { nickName: app.globalData.userInfo.nickName, avatar: app.globalData.userInfo.avatarUrl }); this.hubConnect.onOpen = res => { console.log("成功开启连接") } this.hubConnect.on("system", res => { wx.showModal({ title: '系统消息', content: res, }) }) this.hubConnect.on("receive", res => { centendata.push({ content: res.msg, time: new Date().toLocaleString(), head_owner: res.avatar, is_show_right: 0 }); this.setData({ centendata: centendata }) }) }
同样在页面销毁时应断开与signalr服务器的连接
onUnload: function () { this.hubConnect.close({ reason: "退出" }) }
发送方法也非常简单,只需要调用sendMessage方法并把用户输入的消息传入就大功告成了,其它就是页面上的处理了
this.hubConnect.send("sendMessage",message);
需要注意的是在打开小程序代码时,请修改project.config.json文件中的appid,如果项目不错的话还请大家follow一下本人