Asp.net 利用SignalR实现在线聊天系统

先看下最终实现效果图

预览地址:http://www.mkadmin.cn/

开发步骤:

一:因为整个推送都是使用SignalR来完成,所以先添加引用SignalR

   Install-Package Microsoft.AspNet.SignalR

二:编写代码,由于篇幅原因,这里只暂时核心代码

  1. SignalR后台推送逻辑

public class HubMain : Hub
{
    //保存客户端链接
    public static List<UserChatIdentifyMainInfo> userHubMain = new List<UserChatIdentifyMainInfo>();
    public static object SetParamLock = new object();

    public void InitConnection(UserChatIdentifyMainInfo clientInfo)
    {
        //防止多个线程同时进入
        lock (SetParamLock)
        {
            if (clientInfo == null)
            {
                clientInfo = new UserChatIdentifyMainInfo();
            }
            string connectionId = Context.ConnectionId;

            var connList = userHubMain.Where(q => q.ConnectionId == connectionId);
            if (!connList.Any())
            {
                clientInfo.HeadUrl = $"/images/userHead/{(new Random()).Next(1, 100).ToString()}.jpg";
                clientInfo.NickName = (new Random()).Next(1000, 9999).ToString();
                clientInfo.ConnectionId = connectionId;

                //新增
                userHubMain.Add(clientInfo);

                //通知其他客户端有新用户上线
                List<string> connectionIds = userHubMain.Where(q => q.ConnectionId != connectionId).Select(q => q.ConnectionId).ToList();

                if (connectionIds != null && connectionIds.Count > 0)
                {
                    Clients.Clients(connectionIds).noticeClientOnLine(clientInfo);
                }

                //通知自己所有客户端信息
                var otherClients = userHubMain.Where(q => q.ConnectionId != connectionId).ToList();
                if (otherClients.Any())
                {
                    Clients.Client(connectionId).loadClientAll(otherClients);
                }
            }

            Thread.Sleep(200);
        }
    }

    public override Task OnDisconnected(bool stopCalled)
    {
        string connectionId = Context.ConnectionId;
        //移除客户端链接
        userHubMain = userHubMain.Where(q => q.ConnectionId != connectionId).ToList();

        //通知客户端
        List<string> connectionIds = userHubMain.Select(q => q.ConnectionId).ToList();

        if (connectionIds != null && connectionIds.Count > 0)
        {
            Clients.Clients(connectionIds).noticeClientOnDisconnected(connectionId);
        }

        return base.OnDisconnected(stopCalled);
    }

    #region 发送消息
    /// <summary>
    /// 发送消息
    /// </summary>
    /// <param name="groupIdentify"></param>
    public void SendMsg(ChatMsgParamMainInfo content)
    {
        try
        {
            sendMsgToClient(content);
        }
        catch (Exception ex)
        {
            StringBuilder itemS = new StringBuilder();
            itemS.AppendLine("发送消息异常:" + ex.Message);
            LogHelper.Error(itemS.ToString());
        }
    }
    #endregion

    /// <summary>
    /// 发送消息给用户
    /// </summary>
    private void sendMsgToClient(ChatMsgParamMainInfo content)
    {
        string senderConnectionId = Context.ConnectionId;

        string senderNickName = "";
        string senderHeadUrl = "";
        var recevierInfo = userHubMain.Where(q => q.ConnectionId == Context.ConnectionId);
        if (recevierInfo.Any())
        {
            senderNickName = recevierInfo.FirstOrDefault().NickName;
            senderHeadUrl = recevierInfo.FirstOrDefault().HeadUrl;
        }
        var msgContent = new
        {
            senderConnectionId = senderConnectionId,
            senderNickName = senderNickName,
            senderHeadUrl = senderHeadUrl,
            msgType = content.MsgType,
            text = content.Text,
            imgUrl = content.ImgUrl
        };
         Clients.Client(content.ReceiverConnectionId).acceptMsgToClient(msgContent);
    }
}

/// <summary>
/// 建立链接实体对象
/// </summary>
public class UserChatIdentifyMainInfo
{
    /// <summary>
    /// 客户端推送消息链接Id
    /// </summary>
    public string ConnectionId { get; set; }
    /// <summary>
    /// 聊天昵称
    /// </summary>
    public string NickName { get; set; }
    /// <summary>
    /// 聊天头像
    /// </summary>
    public string HeadUrl { get; set; }
}

/// <summary>
/// 聊天实体对象
/// </summary>
public class ChatMsgParamMainInfo
{
    /// <summary>
    /// 接收者对象客户端Id(用来推送消息)
    /// </summary>
    public string ReceiverConnectionId { get; set; }
    /// <summary>
    /// 消息类型(0:文字 1:图片)
    /// </summary>
    public int MsgType { get; set; }
    /// <summary>
    /// 文字内容
    /// </summary>
    public string Text { get; set; }
    /// <summary>
    /// 图片Url
    /// </summary>
    public string ImgUrl { get; set; }
}

2. js代码

signalr建立与后台连接

var chat = $.connection.hubMain;

//客户端账号离线通知
$.connection.hubMain.client.noticeClientOnDisconnected = function (connectionId) {
    //针对离线的用户进行逻辑处理,标识为离线状态...
};
//客户端账号上线通知
$.connection.hubMain.client.noticeClientOnLine = function (clientInfo) {
    //加载新用户到菜单列表中...
};
//接收新消息
$.connection.hubMain.client.acceptMsgToClient = function (content) {
    //处理新消息,写自己逻辑...
};

$.connection.hub.start().done(function () {
    chat.server.initConnection();
}).fail(function () {
    console.log('连接失败');
});

html页面不做展现,写个简单页面就可以

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值