天天看点

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(七)之LayIM与MVC数据交互实现单聊和群聊

前言

本系列文章特点:使用ASP.NET SignalR和LayIM快速入门对接,实现一对一聊天,群聊,添加聊天群组,查找聊天记录等功能。源代码不包含LayIM的源代码,因为官方并没开源属于收费资源,所以得遵从官方的规则,但包含Demo的数据库脚本和改造之后的find.html,源代码在最后一节。

文章目录:

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(一)之效果展示与关键技术简介

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(二)之后台数据库创建

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(三)之LayIM初始化数据

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(四)之ASP.NET SignalR核心功能介绍

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(五)之使用RabbitMQ缓存消息

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(六)之SignalR与MVC结合封装消息发送与接收

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(七)之LayIM与MVC数据交互实现单聊和群聊

LayIM 3.9.1与ASP.NET SignalR实现Web聊天室快速入门(八)之改造查找页面实现拉取好友创建群

一、本文目标与简介

前面已经讲述了如何MVC和Hub结合,本文将讲述LayIM和MVC进行数据交互从而实现Web聊天室的核心功能单聊和群聊功能以及上传图片和文件。

二、LayIM消息发送监控

LayIM官网提供了如何监控消息发送的代码,也提供了必须的数据格式,这里不再赘述,详细内容请查看官网,官网给的例子如下:

layim.on('sendMessage', function(res){})
           

这里注意的是,不管是单聊还是群聊还是发送图片文件都会监控的到,函数参数res里面包含了发送者和接受者的很多信息能满足我们所需要的数据。

三、上传文件和图片

官网也给我们提供了上传文件和图片的代码样例以及必须符合的返回数据的格式,其实文件和图片返回的格式都一样,所以在前面的文章中,我也将这两个功能放在同一个Action里面即UploadFileAndImg()。LayIM官网也说明了如何在前端配置上传文件,本Demo的代码关键点如下:

, uploadImage: {
                        url: '/LIM/UploadFileAndImg' //接口地址
                        , type: 'post' //默认post
                    }

                    //上传文件接口(返回的数据格式见下文),若不开启文件上传,剔除该项即可
                    , uploadFile: {
                        url: '/LIM/UploadFileAndImg' //接口地址
                        , type: 'post' //默认post
                    }
           

四、获取群成员

在获取初始化数据的时候,已经将当前用户的所有群查出来了,但是并不包含群的成员,官网也给了如何配置获取群成员,官网的例子与说明如下:

,members: {
  url: ' '/api/im/getMembers/'
  ,data: {}
}     
           

那么当点击群聊面板查看成员时,将会向members的url发送Ajax请求,并自动传递一个id参数(群组id)。该接口所返回的信息(response)应该严格按照下述的JSON格式:

{
  "code": 0 //0表示成功,其它表示失败
  ,"msg": "" //失败信息
  ,"data": {
    "list": [{
      "username": "马小云" //群员昵称
      ,"id": "168168" //群员id
      ,"avatar": "http://tp4.sinaimg.cn/2145291155/180/5601307179/1" //群员头像
      ,"sign": "让天下没有难写的代码" //群员签名
    }, …… ]
  }
} 
           

上面官网已经说明的很清楚了,那么本Demo对应的代码如下:

, members: {
       url: '/LIM/GetRoomMember' //接口地址(返回的数据格式见下文)
       , type: 'get' //默认get,一般可不填
       , data: {} //额外参数
            }
           

对应的Action为:

public ActionResult GetRoomMember(int id)
        {
            var result = LIMRepository.GetRoomMember(id);
            return Json(result, JsonRequestBehavior.AllowGet);
        }
           

这个Action返回的是符合官网数据格式的JSON字符串,对应的实体类型RoomMemberDoEntity,具体代码如下:

/// <summary>
    /// 查询群组成员实体
    /// </summary>
    public class RoomMemberDoEntity
    {
        /// <summary>
        /// 0表示成功,其它表示失败
        /// </summary>
        public int code { get; set; } = 0;
        /// <summary>
        /// 失败信息
        /// </summary>
        public string msg { get; set; }

        public RoomMemberList data { get; set; }

    }
    public class RoomMemberList
    {
        public List<LIMMemberInfo> list { get; set; }
    }
           

五、与Action数据交互实现群聊与单聊

经过前文的准备,基本上所有的数据准备工作已经完成,最后一点就是如何在前端LayIM中和Action进行数据交互了。这里需要注意两个地方,一个是SignalR建立连接和监控消息的接收,一个是LayIM监控消息的发送。所以如下代码至关重要:

var conn = $.connection.hub;//SignalR
                //2. 与生成的代理类建立连接
                var proxy = $.connection.ChatHub;
           

SignalR监控消息的接收的函数是:

proxy.client.receiveMsg = function (data) {}
           

SignalR创建连接的函数是:

conn.start().done(function () {}
           

并且从这个函数里可以获取连接成功与否的状态,可以通过conn.state获取。当为1的时候表示成功。

所以结合上文,所有LayIM配置以及与SignalR结合绑定的代码如下:

$(function () {
            layui.use(['layim'], function (layim) {
                //基础配置
                layim.config({
                    title: '三国精英通讯'
                    , init: {//获取主面板列表信息
                        url: '/LIM/GetInitData'
                        , type: 'get'
                    }

                    //获取群员接口(返回的数据格式见下文)
                    , members: {
                        url: '/LIM/GetRoomMember' //接口地址(返回的数据格式见下文)
                        , type: 'get' //默认get,一般可不填
                        , data: {} //额外参数
                    }

                    //上传图片接口(返回的数据格式见下文),若不开启图片上传,剔除该项即可
                    , uploadImage: {
                        url: '/LIM/UploadFileAndImg' //接口地址
                        , type: 'post' //默认post
                    }

                    //上传文件接口(返回的数据格式见下文),若不开启文件上传,剔除该项即可
                    , uploadFile: {
                        url: '/LIM/UploadFileAndImg' //接口地址
                        , type: 'post' //默认post
                    }
                    , msgbox: layui.cache.dir + 'css/modules/layim/html/msgbox.html' //消息盒子页面地址,若不开启,剔除该项即可
                    , find: layui.cache.dir + 'css/modules/layim/html/find.html' //发现页面地址,若不开启,剔除该项即可
                    , chatLog: layui.cache.dir + 'css/modules/layim/html/chatlog.html' //聊天记录页面地址,若不开启,剔除该项即可
                });
                layim.on('members', function (obj) {//监听查看群成员
                    console.log(obj);
                });
                var conn = $.connection.hub;//SignalR
                //2. 与生成的代理类建立连接
                var proxy = $.connection.ChatHub;
                proxy.client.ReceiveOwnCid = function (connectionId) {
                    $.ajax({
                        url: "/LIM/AddConnectionId?connectionId=" + connectionId,
                        type: "get",
                        data: {},
                        dataType: "json",
                        success: function (data) {
                            if (!data.result) {
                                alert(data.message);
                            }
                        },
                        error: function (err) {
                            console.log(err);
                            alert("即时通讯连接错误:" + err.statusText)
                        }
                    });
                }
                proxy.client.receiveMsg = function (data) {
                    console.log(data);
                    var msg = JSON.parse(data);
                    msg.mine = false;
                    layim.getMessage(msg);
                }
                conn.start().done(function () {
                    //3.发送消息
                    layim.on('sendMessage', function (res) {
                        var state = conn.state;
                        var mine = res.mine;
                        var to = res.to; //对方的信息
                        if (state == 1) {
                            var sendmsg = {};
                            sendmsg.username = mine.username;
                            sendmsg.avatar = mine.avatar;
                            sendmsg.id = mine.id;//消息的来源ID(如果是私聊,则是用户id,如果是群聊,则是群组id)
                            sendmsg.type = to.type;
                            sendmsg.mine = mine.mine;
                            sendmsg.content = mine.content;
                            sendmsg.fromid = mine.id;
                            if (sendmsg.type == "group") {
                                sendmsg.id = to.id;
                            }
                            $.ajax({
                                url: "/LIM/SendMessage",
                                type: "post",
                                data: {
                                    fid: mine.id,
                                    tid: to.id,
                                    msg: sendmsg
                                },
                                dataType: "json",
                                success: function (data) {
                                },
                                error: function (err) {
                                    if (err.status != 200) {
                                        console.log(err);
                                        alert("发送消息失败:" + err.statusText)
                                    }
                                }
                            })

                        } else {
                            alert('与服务器失去连接');
                        }
                    })
                }).fail(function () {
                    alert('不能连接到服务器');
                });

            });
        })
           

六、总结

到这里,就已经能使用LayIM进行单聊以及群聊了,可以通过打开多个浏览器窗口,登陆不同的用户进行测试,另外上传文件图片,通过RabbitMQ实现消息缓存,用户登陆后就可以接受到之前未读的消息。所涉及的关键的技术点已经都有说明,还有一些其他的点,可以查看Demo的源代码,源代码在最后一节可以下载。