SignalR+MongoDB实现用户留言即时推送

前言:

最近写了一个项目,要实现即时通讯功能,在网上查了一下有两种常见的实现方式:SignalR和WebSocket,SignalR是封装好的一个类库,有三种传输模式:LongLooping(长轮询)、WebSocket、Forever Frame(隐藏框架的长请求连接),它会根据浏览器的环境自动选择合适的传输方式(比如说低版本的IE浏览器不支持WebSocket,SiganlR就会采用长轮询的方式传输)。SiganlR的介绍可以在百度搜一下有很多,这篇博客简单的介绍一下如何用SiganlR实现一个实时的消息推送功能。

一开始用户留言是存到SqlServer中的,考虑到用户留言价值相对较低,数据量大的特点,用MongoDB在性能上比较有优势(不用写Sql了,干活好快)

实现步骤:


1.安装SignalR

Install-Package Microsoft.AspNet.SignalR

安装成功后会系统会新增对应的js文件

2.创建Connections文件夹,存放永久连接类和Startup.cs

创建永久连接类:

代码:

    public class ChatConnections : PersistentConnection
    {
        protected override Task OnConnected(IRequest request, string connectionId)
        {
            return null;
        }

        protected override Task OnReceived(IRequest request, string connectionId, string data)
        {
            return Connection.Broadcast(data);
        }
    }
View Code

创建startup类,如果项目中已经有了就不用创建了

代码:

    public class Startup1
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR<ChatConnections>("/Connections/ChatConnections");
        }
    }
View Code

3.用户发送留言

SignalR推送消息给后台->留言写入MongoDB

1.页面引入jquery.signalR-2.4.0.js和jquery

js:

<script src="~/layer/layer.js"></script>
<script src="~/scripts/jquery-1.10.2.min.js"></script>
<script src="~/scripts/jquery.signalR-2.4.0.js"></script>
<script type="text/javascript">
    $(function () {
        //获取连接
        var connection = $.connection("/Connections/ChatConnections");
        //监听消息,用户端不用做处理
         connection.received(function (data) {
        });
     // Wire up Send button to call NewContosoChatMessage on the server.
        connection.start().done(function () {
            $("#btn1").click(function () {
                layer.msg('确定发起留言?', {
                    time: 0 //不自动关闭
                    , btn: ['确定', '取消']
                    , btn1: function (index) {
                        //加载层
                        var index = layer.load(1, {
                            shade: [0.1, '#fff']
                        });
                        $.ajax({
                            type: "post",
                            url: "/User/Message/SendMessage",
                            data: $('#form1').serialize(),
                        }).success(function (message) {
                           //消息推送
                            connection.send(message);
                            layer.msg(message, { icon: 1 });
                            var index = parent.layer.getFrameIndex(window.name);//获取当前弹出层的层级
                            window.parent.location.reload();//刷新父页面
                            parent.layer.close(index);//关闭弹出层
                        }).fail(function (err) {
                            layer.msg('系统错误,请稍后重试', { icon: 2 });
                        })
                        layer.close(index)//关闭加载层
                    }, btn2: function (index) {
                        layer.close();
                    }
                });
            });
        });

    });
</script>     
View Code

控制器:

        public async Task<JsonResult> SendMessage(MessageReq req)
        {
            SessionModel session = SessionInfo.GetSession();
            var info = _mysqlRepository.GetUserInfo(session.UserCode);
            req.SendName = info.UserName;
            req.SendCode = info.UserCode;
            req.SendPhone = info.Phone;
            //写入MongoDB
            if (! await _mongoRepository.InsertMessage(req))
            {
                return Json("留言失败");
            }
            return Json("留言成功");
        }
        #endregion
View Code

4.管理员接收留言:

SignalR监听用户发送留言,刷新页面时查询MongoDB里是否有未读留言

js:

<script src="~/scripts/jquery.signalR-2.4.0.min.js"></script>
<script>
    $(function () {
        //监听用户发送留言
        var connection = $.connection("/Connections/ChatConnections");
        connection.received(function (data) {
            layer.closeAll();
            layer.open({
                type: 2,
                shade: [0],
                title: '您有新的留言',
                shadeClose: true,
                shade: false,
                area: ['280px', '215px'],
                content: ['/Manager/Home/Ifarme', 'no'], //iframe的url,no代表不显示滚动条
                offset: 'rb' //右下角弹出
            });
        });

        connection.start().done(function () {
        });
        //刷新页面查询是否有未读留言
        $.ajax({
            type: "post",
            url: "/Manager/Home/QueryExist"
        }).success(function (message) {
            if (message == "Yes") {
                layer.open({
                    type: 2,
                    shade: [0],
                    title: '您有新的留言',
                    shadeClose: true,
                    shade: false,
                    area: ['280px', '215px'],
                    content: ['/Manager/Home/Ifarme', 'no'], //iframe的url,no代表不显示滚动条
                    offset: 'rb' //右下角弹出
                });
            }
        }).fail(function (err) {
            layer.msg('未能读取未读留言', { icon: 2 });
        })
    });
</script>
View Code

控制器:

        /// <summary>
        /// 查询是否有未读留言
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResult> QueryExist()
        {
            var result = await _msg.QueryExist();
            if (!result)
            {
                return Json("No");
            }
            return Json("Yes");
        }
View Code

点击留言标为已读:

        /// <summary>
        /// 标为已读
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<JsonResult> AlRead(string id)
        {
            if (! await _mongoRepository.AlRead(id))
            {
                return Json("操作失败", JsonRequestBehavior.AllowGet);
            }
            return Json("成功", JsonRequestBehavior.AllowGet);
        }
View Code

到这里用户->管理员的实时消息推送就实现了

效果图:

写在最后:博主本人也是最近刚学SignalR,说的有不对的地方,请各位大佬指点,相互学习,在此我也会深入的学习SignalR,后续会继续分享SignalR的学习记录

原文地址:https://www.cnblogs.com/quebra/p/10200766.html