apicloud apicloud

注册
查看: 18320|回复: 31

[模块教程] 【融云教程第二弹】会话列表及获取最新会话消息

主题:
53
帖子:
333
云币:
552

APICloud粉丝APICloud毕业勋章一周年

[模块教程] 【融云教程第二弹】会话列表及获取最新会话消息

18320 31 | 发表于 2015-4-15 03:13:37 |阅读模式 | |
本帖最后由 流浪男 于 2015-6-29 19:23 编辑

融云最新教程请参考 https://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=8715

在做会话列表页的时候发现了不少问题,首先我也是第一次使用apicloud和融云,下面讲的可能不是最好的办法,如果有更好的办法欢迎分享。
首先说一下会话列表页实现的思路
一,使用 getConversationList 方法来获得全部会话列表,但是这样直接获得的列表并不是我们想要的,rongCloud的会话列表出现了两种情况:
      (1)发送者等于本地用户 (2)接收者等于本地用户
     后面实现的功能是只获得接收者为本地用户的情况
二,获得会话列表后将列表内容插入容器中,同时加载用户信息(主要为头像和昵称)
三,监听是否有最新消息写入,我这里实现的逻辑是加载完列表后再来监听,这个就根据自己的需要来就行了。
四,如果有新消息进来,两种情况
       (1)发送者已在会话列表中存在--->更新会话内容及时间
       (2)不存在--->写入容器
五,点击会话列表页进入会话窗口,这里遇到了几个问题没能很好的解决,就使用了一个比较笨的办法。
        问题:因为会话列表页在监听消息,当打开聊天页面也会在监听最新消息,中间可能会有冲突导致页面无法正常监听
        我的解决方案(这个方法可能有点笨):
        当打开聊天页面后,关闭会话列表页rongcloud的连接--------关闭聊天页面时关闭聊天页面的连接并重新打开会话列表页的连接,同时监听最新消息并更新下
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这节主要先讲下会话列表页的实现,会涉及到第五点的解决方案,后面的时候会具体介绍
一、会话列表的样式就不介绍了
      默认容器<div id="conversationList"></div>

     JS
      <script src="../script/zepto.min.js"></script>
      <script type="text/javascript" src="../script/api.js"></script>
二、功能部分
      自定义函数类解释:
      getMessageList();--------------从apicloud获取会话列表
      insterData(data);--------------将会话内容插入容器
      newMessage();----------------最新消息
      insertNewData();---------------最新消息更新或写入
      getUserInfo(uid);    getUserInfos();-------------获取单个和多个用户信息
      chat(touserid);-------------------打开聊天窗口
      getDateDiff();----------------------处理时间戳的函数,将时间戳变为“刚刚,几分钟钱的形式
    --------------------------------------------------------------------------------------------------------------
下面就按流程来讲了,代码说明就在注释中说了(完整的演示就不发了,把下面的代码稍微整理下放入<script>中就可以使用,都是按顺序弄出来的)
   首先还是要apiready下
apiready = function() {
        var mytoken = $api.getStorage('token');//从本地获取我的token
        //api.addEventListener为处理上面第五步时的解决方案,当聊天窗口关闭时,该页面重新链接rongcloud,并加载监听最新消息事件
        api.addEventListener({
        name: 'reListen'
    }, function(ret){
        if(ret){
            var value = ret.value;
            if(value.status=='true'){
                                var rong = api.require('rongCloud');
                                rong.init(function(ret, err){
                                        //alert(ret.status);
                                });
                                rong.connect({
                                            token: mytoken
                                    },
                                    function(ret, err){
                                        }
                                );
                                rong.reconnect();
                newMessage();
            }
        }
    });        
    //获取会话列表
    getMessageList();            
};


获取来自apicloud的会话列表
function getMessageList(){
        var mytoken = $api.getStorage('token');
        var rong = api.require('rongCloud');
        rong.init(function(ret, err){        
        });
        rong.connect({
                    token: mytoken
            },
            function(ret, err){
                        if(ret.status=="success"){
                rong.getConversationList(function (ret, err) {
                        //将获得的数据插入到容器中
                                    insertData(ret.result);
                                })
                        };
                }
        );
}


//插入数据
function insertData(data) {
        var msgData='';//初始化
        var myuserid = $api.getStorage('myuserid');//从本地数据获取我的用户ID,用来判断发送者是否为本地用户
        for(var i in data){
                if(data.latestMessage.text && data.senderUserId){
                        //两种情况,1当发送者等于本地用户时 2.当接收者等于本地用户时,只获取接受到的信息,不获取发送的信息
                        if(data.senderUserId!=myuserid){
                                //当发送者不等于本地用户时
                                msgData += '<li id="messageBox_"'+data.senderUserId+'" uid="'+data.senderUserId+'" msgId="'+data.messageId+'">';
                                //头像
                                msgData += '<div class="message-useravatar"><img id="avatar_'+data.senderUserId+'" src="../image/imgloading.gif" width="60" height="60"/></div>';
                                msgData += '<div class="message-content">';
                                //昵称
                                msgData += '<p class="message-nickname">';
                                msgData += '<span class="message-time" id="messageTime_'+data.senderUserId+'">' + getDateDiff(data.receivedTime) + '</span>';
                                msgData += '<span id="nickname_'+data.senderUserId+'"></span>';
                                msgData += '</p>';
                                //内容
                                msgData += '<p id="messageText_'+data.senderUserId+'">' + data.latestMessage.text + '</p>';
                                msgData += '</div>';
                                msgData += '</li>';
                        }
                        
                }
        }
        $("#conversationList").append(msgData);
        getUserInfos();//获取会话列表中用户的信息
        newMessage();//我的监听最新消息事件是从这里开始的,当会话列表全部处理完成后再开始监听最新消息
}


//监听消息
function newMessage(mytoken){
        var mytoken = $api.getStorage('token');
        var rong = api.require('rongCloud');
        rong.init(function(ret, err){
                //alert(ret.status);
        });
        rong.setOnReceiveMessageListener(function (ret, err) {
                insertNewData(ret.result.message);//写入信息消息
        })
        rong.connect({
                    token: mytoken
            },
            function(ret, err){
                }
        );
}
function insertNewData(data){
        var myuserid = $api.getStorage('myuserid');
        var senderUserId = data.senderUserId;
        //判断是否存在当前发送者的会话
        var messageInfo = $("#messageBox_"+senderUserId);
        if(messageInfo){
                //如果存在更新发送时间及内容
                var msgId = data.messageId;
                $("#messageTime_"+senderUserId).html(getDateDiff(data.sentTime));
                $("#messageText_"+senderUserId).html(data.content.text);
        }else{
                //不存在插入
                var msgData = "";
                if(data.senderUserId!=myuserid){
                        //当发送者不等于本地用户时
                        msgData += '<li id="messageBox_"'+data.senderUserId+'" uid="'+data.senderUserId+'" msgId="'+data.messageId+'">';
                        //头像
                        msgData += '<div class="message-useravatar"><img id="avatar_'+data.senderUserId+'" src="../image/imgloading.gif" width="60" height="60"/></div>';
                        msgData += '<div class="message-content">';
                        //昵称
                        msgData += '<p class="message-nickname">';
                        msgData += '<span class="message-time" id="messageTime_'+data.senderUserId+'">' + getDateDiff(data.receivedTime) + '</span>';
                        msgData += '<span id="nickname_'+data.senderUserId+'"></span>';
                        msgData += '</p>';
                        //内容
                        msgData += '<p id="messageText_'+data.senderUserId+'">' + data.content.text + '</p>';
                        msgData += '</div>';
                        msgData += '</li>';
                        $("#conversationList").prepend(msgData);
                        getUserInfo(data.senderUserId);
                }
        }
}


聊天窗口打开
function chat(touserid) {
        var mytoken = $api.getStorage('token');
        var rong = api.require('rongCloud');
        rong.init(function(ret, err){
                //alert(ret.status);
        });
        rong.connect({
                    token: mytoken
            },
            function(ret, err){
                }
        );
        rong.disconnect(false);//注意这里为了处理第五点的不冲突,就绝情的把链接关闭了

        //打开聊天窗口,根据自己的实际情况来
        api.openWin({
                name : 'chat',
                url : 'chat.html',
                pageParam : {
                        touserid : touserid
                },
                vScrollBarEnabled : false
        });
}



下面为获取用户信息及处理时间戳的函数

function getUserInfo(uid){
        var i = 0,data = {};
        data[0] = uid;
        $.post(url,{data:data},function(result){
                if(result){
                        for(var d in result){
                                $("#avatar_"+result[d].userid).attr("src",result[d].avatar);
                                $("#nickname_"+result[d].userid).html(result[d].nickname);
                        }
                }
               
        },'json');        
}
function getUserInfos(){
        var i = 0,data = {};
        $("#conversationList li").each(function(){
                var t = $(this);
                data = t.attr("uid");
                i++;
        })
        $.post(url,{data:data},function(result){
                if(result){
                        for(var d in result){
                                $("#avatar_"+result[d].userid).attr("src",result[d].avatar);
                                $("#nickname_"+result[d].userid).html(result[d].nickname);
                        }
                }
               
        },'json');        
}
//处理时间戳
function getDateDiff(dateTimeStamp){
        var minute = 1000 * 60;
        var hour = minute * 60;
        var day = hour * 24;
        var halfamonth = day * 15;
        var month = day * 30;
        var now = new Date().getTime();
        var diffValue = now - dateTimeStamp;
        if(diffValue < 0){
                //若日期不符则弹出窗口告之
                //alert("结束日期不能小于开始日期!");
        }
        var monthC =diffValue/month;
        var weekC =diffValue/(7*day);
        var dayC =diffValue/day;
        var hourC =diffValue/hour;
        var minC =diffValue/minute;
        if(monthC>=1){
                result= parseInt(monthC) + "个月前";
        }else if(weekC>=1){
                result=parseInt(weekC) + "周前";
        }else if(dayC>=1){
                result=parseInt(dayC) +"天前";
        }else if(hourC>=1){
                result= parseInt(hourC) +"个小时前";
        }else if(minC>=1){
                result=parseInt(minC) +"分钟前";
        }else{
                result="刚刚";
        }
        return result;
}


----------------------------------------------------
php端处理用户返回用户的信息函数参考
        public function getUserInfo(){
                $data = $_POST['data'];
                foreach ($data as $key => $v) {
                        $userInfo = mysql语句;
                        $result[$key]['userid'] = $v;
                        $result[$key]['nickname'] = $userInfo['nickname'];
                        $result[$key]['avatar'] = $userInfo['avatar'];
                }
                echo json_encode($result);
        }



在用get或者post方法时,个人觉得最后传入本地用户ID及key来验证用户,这样稍微安全一点


后面的时候再讲聊天窗口打开和关闭时的处理,其实也比较简单
打开的时候重新连接一下融云     reconnect
关闭的时候disconnect一下,然后发送一个事件  sendEvent
var mytoken = $api.getStorage('token');
var rong = api.require('rongCloud');
rong.init(function(ret, err){
        //alert(ret.status);
});
rong.connect({
            token: mytoken
    },
    function(ret, err){
        }
);
rong.disconnect(false);
api.sendEvent({
    name: 'reListen',//注意这个要跟会话列表页的对应
    extra:{status:'true'}
});
api.closeWin(
);


到此又结束了,老规矩不明白的在下面留言,或者有更好思路的可以提出来一块解决,谢谢支持
1

查看全部评分

主题:
53
帖子:
333
云币:
552

APICloud粉丝APICloud毕业勋章一周年

 楼主| 发表于 2015-4-28 13:02:27 |

只是简单的功能实现,如果什么都做好了,自己就学不到什么东西了,自己可以参考去扩展一下

实习司机

UID:20052

主题:
12
帖子:
68
云币:
14

你吃屎!女朋友

发表于 2015-4-15 06:40:46 |
强贴支持

驾校小白

UID:11283

主题:
47
帖子:
193
云币:
2237

APICloud粉丝社会摇托马斯全旋女朋友超人

发表于 2015-4-15 08:37:51 |
不得不顶

主题:
8
帖子:
79
云币:
198
发表于 2015-4-15 09:09:37 |
地毯~~~需要更多教程~~

业余车手

UID:22235

主题:
89
帖子:
1166
云币:
10259

版主勋章APICloud粉丝端午节

发表于 2015-4-16 17:33:42 |
好贴,好人!

业余车手

UID:22235

主题:
89
帖子:
1166
云币:
10259

版主勋章APICloud粉丝端午节

发表于 2015-4-16 17:33:52 |
继续,让后放代码!

新手上路

UID:71889

主题:
30
帖子:
74
云币:
42
发表于 2015-4-21 09:06:11 |
66666666666666

驾校小白

UID:27723

主题:
4
帖子:
10
云币:
49
发表于 2015-4-25 18:56:01 |
这个列表怎么保存到本地?

主题:
20
帖子:
203
云币:
280
发表于 2015-4-28 11:57:44 |
图片 还有语音呢?
1234下一页
您需要登录后才可以回帖 登录 | 立即注册

快速回复 返回顶部 返回列表