基于.Net Core3.1 与signalR实现一个即时通讯工具(三)——项目创建
一、创建项目
- 打开VS2019,选择创建项目,在下面模板中选择 ASP.NET Core Web应用(模型-视图-控制器),然后下一步,等待模板创建。
2. 目录结构如下
- 根目录下新建文件夹Hubs并创建相关类
IMHub.cs
using Microsoft.AspNetCore.SignalR;
using MySql.Data.MySqlClient.Memcached;
using SpoonRapidCore.DataBaseHelper;
using SRFEntity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SRF.IM.Hubs
{
public class IMHub : Hub
{
#region 数据库操作类(用于保存消息记录,用户上线信息等)
private ISqlSugarHelper<Base_User> userHelper = new SqlSugarHelper<Base_User>();
private ISqlSugarHelper<Base_HistoryMeeting> meetingHelper = new SqlSugarHelper<Base_HistoryMeeting>();
private SqlSugarHelper<Base_Msg> msgHelper = new SqlSugarHelper<Base_Msg>();
#region
#region 发送至客户端
/// <summary>
/// 像所有在线通讯广播
/// </summary>
/// <param name="Message"></param>
/// <param name="Name"></param>
/// <returns></returns>
public async Task SendNotice(string Message, string Name = "系统提示")
{
await Clients.All.SendAsync("RNotice", Name, Message);
}
/// <summary>
/// 通过连接ID向指定通讯发送消息
/// </summary>
/// <param name="ConnectionID"></param>
/// <param name="SendUser"></param>
/// <param name="Message"></param>
/// <returns></returns>
public async Task SendMessage(string ConnectionId,string SendUser, string Message)
{
await Clients.User(ConnectionId).SendAsync("RMessage",SendUser, Message);
}
/// <summary>
/// 通过多个连接ID向指定通讯发送消息
/// </summary>
/// <param name="ConnectionIDs"></param>
/// <param name="SendUser"></param>
/// <param name="Message"></param>
/// <returns></returns>
public async Task SendMessages(List<string> ConnectionIds, string SendUser, string Message)
{
await Clients.Users(ConnectionIds).SendAsync("RMessages",SendUser, Message);
}
public async Task SendLog(string ConnectionId, string SendUser, string Message)
{
await Clients.User(ConnectionId).SendAsync("SendLog", SendUser, Message);
}
#endregion
#region 服务端接受
/// <summary>
/// 客户端上线
/// </summary>
/// <param name="UserId"></param>
/// <param name="LoginStatus"></param>
/// <param name="UserName"></param>
/// <returns></returns>
public async Task ConnectedOn(string UserId, string LoginStatus,string UserName)
{
string connectionId = Context.ConnectionId;
try
{
var isExist = userHelper.GetEntity(UserId);
Base_User base_User = new Base_User
{
ConnectId = connectionId,
IsOnline = 1,
LoginDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
UserId = UserId,
};
if (isExist == null)
{
userHelper.SaveForm(base_User);
}
else
{
isExist.ConnectId = connectionId;
isExist.IsOnline = 1;
isExist.LoginDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
isExist.UserId = UserId;
userHelper.UpdateEntity(isExist);
}
await SendLog(connectionId, UserId, "您已连接到IM,您的连接ID为:" + connectionId + ",您的登录状态为:" + LoginStatus);
}
catch (Exception ex)
{
await SendLog(connectionId, UserId, "连接失败!失败原因为:"+ex.Message);
}
}
/// <summary>
/// 会话上线
/// </summary>
/// <param name="UserId"></param>
/// <param name="ToUserId"></param>
/// <returns></returns>
public async Task MeetingConnectOn(string UserId, string ToUserId)
{
try
{
string connectionId = Context.ConnectionId;
/*判断该会话是存在*/
StringBuilder H_SqlWhere=new StringBuilder();
H_SqlWhere.AppendFormat(" AND MeetingOwn='{0}' AND UserId='{1}'",UserId,ToUserId);
var HMeeting = meetingHelper.GetEntityByWhereSql(H_SqlWhere.ToString());
if (HMeeting == null)
{
HMeeting = new Base_HistoryMeeting
{
HistoryDate = DateTime.Now,
HistoryId = Guid.NewGuid().ToString(),
MeetingOwn = UserId,
UserId = ToUserId,
OwnCID = Context.ConnectionId,
};
meetingHelper.SaveForm(HMeeting);
}
else
{
HMeeting.OwnCID = Context.ConnectionId;
HMeeting.HistoryDate = DateTime.Now;
meetingHelper.UpdateEntity(HMeeting);
}
/*所有会话设置已读*/
StringBuilder MsgRead_StrSql = new StringBuilder();
MsgRead_StrSql.AppendFormat("UPDATE dbo.Base_Msg SET MsgStatus=0 WHERE ToUser='{0}' AND FromUser='{1}' AND MsgStatus=1", UserId, ToUserId);
msgHelper.ExecuteCommand(MsgRead_StrSql.ToString());
await SendLog(Context.ConnectionId, UserId, "会话建立成功!");
}
catch (Exception ex)
{
await SendLog(Context.ConnectionId, UserId, "会话建立失败!失败原因为:" + ex.Message);
}
}
/// <summary>
/// 会话关闭
/// </summary>
/// <param name="UserId"></param>
/// <param name="ToUserId"></param>
/// <returns></returns>
public async Task MeetingConnectOff(string UserId, string ToUserId)
{
try
{
StringBuilder GetConnectionIdStrSql = new StringBuilder();
GetConnectionIdStrSql.AppendFormat(" AND MeetingOwn='{0}' AND UserId='{1}'", ToUserId, UserId);
Base_HistoryMeeting ToUserMeeting = meetingHelper.GetEntityByWhereSql(GetConnectionIdStrSql.ToString());
StringBuilder H_SqlWhere = new StringBuilder();
H_SqlWhere.AppendFormat(" AND MeetingOwn='{0}' AND UserId='{1}'", UserId, ToUserId);
var HMeeting = meetingHelper.GetEntityByWhereSql(H_SqlWhere.ToString());
HMeeting.OwnCID = "";
meetingHelper.UpdateEntity(HMeeting);
//meetingHelper.DeleteByKey(HMeeting);
await SendLog(Context.ConnectionId, UserId, "会话关闭成功");
}
catch (Exception ex)
{
await SendLog(Context.ConnectionId, UserId, "会话关闭失败!失败原因为:" + ex.Message);
}
}
#endregion
#region 服务端对连接管理
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}
#endregion
}
}
IMHubServices
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SRF.IM.Hubs
{
public interface IMHubServices
{
Task RNotice(string Message, string Name = "系统提示");
Task RMessage(string SendUser, string Message);
Task RMessages(string SendUser, string Message);
}
}
- Startup.cs 配置
添加引用:
using SRF.IM.Hubs;
ConfigureServices里添加:
services.AddSignalR();
Configure里添加:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=IM}/{action=Index}/{id?}");
endpoints.MapHub<IMHub>("/IMHub");
});
-
创建控制器
IMController -
创建视图
ChatBox.cshtml
ChatIndex.cshtml
Index.cshtml -
创建实体类类库
-
导入我封装的sqlSugarHelper
下载地址:基于SqlSuagr封装的辅助类
-
此时程序可能会有报错,提示找不到 signalR,别着急向下看。
二、引入包
- 如果你的模板里没有signalR的话,打开nuget控制台输入:
Install-Package Microsoft.AspNetCore.SignalR -Version 1.1.0
- 我项目里使用的是sqlSugar ORM框架所以也要引入这个包
Install-Package SqlSugarCore -Version 5.0.0.15
如何配置sqlsugar 可以看我另一篇博客
总结
项目基础结构创建完成,下面开始进行功能的实现!