以下所有内容均为本人自己开发总结的经验,如有雷同,不胜荣幸!

最近公司在做一款app,app里面涉及到与客服聊天功能。

于是公司就接入了融云api聊天系统。

app端(前端)聊天由专业的ios andorid开发人员完成,我负责开发后台客服聊天即可。

目前使用的是ssm 4.0框架,jdk1.8

框架就自行搭建了。能运行就行。下面就详细聊聊接入融云,并开发聊天。

注:融云是收费的。各位看官如果是使用收费模式,则不需要观看该文章,因为我是自行开发的。

涉及功能:1对1聊天,聊天记录存储,会话列表,未读消息,是否在线(这些功能属于后台,前端的我不管。)

1:1vs1 聊天,(从app端看来是用户对客服1vs1,从客服对app端则是1vs n)(n:即多个用户,所以这边会有会话聊天列表)

因为只有1对1聊天是免费的。所以除了1对1聊天,其他功能全部本地开发,并未使用融云api。

融云api配置我就不说了。网上一大堆。随便看看就ok。

配置只有一点要注意:

这个要放进来。这个是融云的聊天格式,

不论是前端还是后端。用户聊天都必须使用token 这是融云要求的。所以获得token是服务端完成的。

如果上面的图片没有放入到项目中,那么你服务端获取token是失败的。

这个坑是摸索半天,看了半天的源码才搞通

String userToken = UserExample.returnToken(users.getUsers_only_md5(), usersInfo.getUsers_info_nick(),RongYunKeyEnum.APPKEY.getValue(),
                    RongYunKeyEnum.APPSECRET.getValue());
            req.setAttribute("userToken", userToken);

returnToken 是我在 UserExample 类里自己封装了方法,当参数传进来而已。自己随便写就行。

服务端token写好了。页面端需要2个值, token 和appKey   用request 传作用域就行

记得返回到聊天的页面来。

融云是用id 作为聊天的唯一对象。所以我这边用自己数据库的唯一列作为传递到融云的id值。所以我传递到页面上,方面2人聊天。

我这边解释下,我是本地跟本地聊天。并未涉及到和app聊天。所以我要区分,该登录是用户还是客服。可以用2个登录方法登录页面来实现。(identity:区分身份(users/manager))

<script type="text/javascript">
    $(document).keyup(function(event){
          if(event.keyCode ==13){
               privateMessage();
          }
    });
    var instance = null;
    var userInfo = {
        appKey : "${appKey}",
        token : "${userToken}"
    };
    function showTips(data){
        var dom = document.getElementById("show");
            dom.style.display = "block";
        if(data){
            dom.innerHTML += "<li>" + data + "</li>";
        }else{
            dom.innerHTML = "";
        }
    }    
    var callbacks = {
        getInstance : function(_instance){
            instance = _instance;
        },
        receiveNewMessage : function(message){
            // 判断消息类型
            showTips("新消息,类型为:" + message.messageType);
            // showResult("新消息",message,start);

console.log("messageUId:" + message.messageUId + ",   messageId:" + message.messageId);
            console.log(message);
        },
        getCurrentUser : function(userInfo){
            userId = userInfo.userId;
            $("#login").val(userId);
            //afterConnected();
        }
    };
    init(userInfo, callbacks);
</script>

页面上这段js 用来初始化融云 或者说用户是否登录成功了。可以F12查看的。

聊天:就是。我发消息给你,你收到消息,你发消息给我,我收到消息。

var recallMessage = null, clearMessage;
    function markMessage(message){
        recallMessage = message;
        clearMessage = message;
    }

// 消息监听器
    RongIMClient.setOnReceiveMessageListener({
        // 接收到的消息
        onReceived: function (message) {
            // 判断消息类型
            console.log(message.content.content);
            if("附加信息" == message.content.extra){
                //这边要修改成
                //是否跟当前用户在聊天
                //判断用户来增加未读数量还是显示在当前了聊天框中
                //所以一下该function需要进行修改。
                //getNewMsgUser();
            }
            //有新消息进来的时候,先进入数据库执行,该用户是否能接收消息,
            //如果不能接收,则进行未读消息数量修改,
            //否则直接进入聊天界面
            
            var htmls = "<div class=\"leftd\">"+
                    "<div style=\"float:left;\">"+
                    "<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
                    "</div>"+
                    "<div class=\"speech left\" style=\"margin-left:61px;\">"+message.content.content+"</div>"+
                    "</div>";
            
            $("#liaotian").append(htmls);
        
            $("#getMessage").val(message.content.content);
            //message接受到的消息(包含发送的信息,也可以在extra中添加要传递的值,如:时间等)
            
            $('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
        }
    });

该方法是用来接收有人发消息过来。中间有一段注释的内容。我还在开发中,你们也可以自己想想,文字描述很清晰

//私聊
    function privateMessage(){
        var sendMsg = $("#sendMessage").val();
        if("" == sendMsg){
            alert("请输入聊天内容");
            $('#sendMessage').focus();
            return;
        }
        var conversationtype = RongIMLib.ConversationType.PRIVATE; // 私聊
        var targetId = $("#toUserId").val(); // 目标 Id
        var msg = new RongIMLib.TextMessage({content:sendMsg,extra:"附加信息"});
        var conversationtype = RongIMLib.ConversationType.PRIVATE; // 单聊,其他会话选择相应的消息类型即可。
        var pushData = "your pushInfo";//这个暂时还没研究
        RongIMClient.getInstance().sendMessage(conversationtype, targetId, msg, {
                onSuccess: function (message) {
                    //发送成功后,将该条发送的消息记录到数据库中
                    //如果数据库插入成功,则进行页面的发送消息append到html聊天框里。
                    
                    var htmls = "<div class=\"rightd\">"+
                    "<div style=\"float:right;\">"+
                    "<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
                    "</div>"+
                    "<div class=\"speech right\" style=\"margin-right:61px;\">"+message.content.content+"</div>"+
                    "</div>";
            
                    $("#liaotian").append(htmls);
                    var sendMsg = $("#sendMessage").val("");
                    console.log(message.content.content);
                    $('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
                    
                },
                onError: function (errorCode,message) {
                   console.log(message.content.content);
                }
            }, false, pushData
        );
    }

该方法就是我发送消息,发送聊天内容等

//获取会话列表
    function findMsgUser(){
        var currUserId = '${currUserId}';
        $.get("${ctx}/webMessageUserList/selectWebMessageUserList.htmls",{only_md5:'${currUserId}'},function(data){
            var objList = eval(data);
            var htmls = "";
            if(objList.code == 20000){
                for(i=0;i<objList.entity.length;i++){
                    var b = objList.entity[i].users_only_md5;
                    if(objList.entity[i].users_only_md5 != currUserId){
                        htmls += "<div style=\"width:180px;height:60px;\" οnclick=\"pushUser('"+objList.entity[i].users_only_md5+"')\">"+
                            "<img alt=\"用户头像\" width=\"40px\" height=\"40px\" src=\""+objList.entity[i].users_info_photo+"\">"+
                            "<label>"+objList.entity[i].users_info_nick+"</label>"+
                            "&nbsp;<label style=\"color:red;\">"+objList.entity[i].web_message_user_list_read_count+"</label></div>";
                    }else{
                        htmls += "<div style=\"width:180px;height:60px;\" οnclick=\"pushMaster('"+objList.entity[i].master_only_md5+"')\">"+
                            "<img alt=\"用户头像\" width=\"40px\" height=\"40px\" src=\""+objList.entity[i].users_info_photo+"\">"+
                            "<label>"+objList.entity[i].users_info_nick+"</label>"+
                            "&nbsp;<label style=\"color:red;\">"+objList.entity[i].web_message_user_list_read_count+"</label></div>";
                    }
                }
            }else{
                var htmls = "<div style=\"width:180px;height:60px;\">"+
                    "<img alt=\"用户头像\" width=\"40px\" height=\"40px\" src=\"${ctx}/img/20180917141606.png\">"+
                    "<label>暂无会话用户</label></div>";
            }
            $("#newMsgUser").html(htmls);
        });
    }

该方法是获取会话列表。因为融云的会话列表是收费的。所以我自己写一个会话列表:

需要创建数据库,然后将客服与用户聊天创建一条会话数据,作为聊天的列表模式,不需要重复创建,需要自己判断,

怎么创建这个数据呢。首先。客服是不能主动找未聊天过的 用户聊!!!!即只有app端先发起客服聊天,客服才有资格去回复。

所以会话列表的数据创建,应该有app端发起时,在接口处去创建会话列表数据。

:目前这一块我还没有写。所以自己创建的几个临时的数据,

而且我这边是本地跟本地聊,即打开2个浏览器去聊。所以暂时还没去写,不过,并不难。

//客服跟用户聊天
    function pushUser(users_only_md5){
        if(toUserId != users_only_md5){
            toUserId = users_only_md5;
            hisHtmls = "";
            $("#liaotian").html(hisHtmls);
            $("#toUserId").val(users_only_md5);
            getHisMsgUser(users_only_md5);
        }
    }

//用户跟客服聊天
    function pushMaster(master_only_md5){
        if(toUserId != master_only_md5){
            toUserId = master_only_md5;
            hisHtmls = "";
            $("#liaotian").html(hisHtmls);
            $("#toUserId").val(master_only_md5);
            getHisMsgMaster(master_only_md5);
        }
    }

有以上2个方法,是因为我用2个浏览器去聊天的,所以要区分开用户和客服。

//获取跟该用户的历史聊天记录
    function getHisMsgUser(users_only_md5){
        if(regNull(hisHtmls)){
            $.get("${ctx}/webMessage/selectWebMessageUsers.htmls",
            {
                users_only_md5:users_only_md5,
                master_only_md5:'${currUserId}'
            },
            function(data){
                var obj = eval(data);
                pushHTML(obj.entity,"users");
            });
        }
    }

//获取跟该客服的历史聊天记录
    function getHisMsgMaster(master_only_md5){
        if(regNull(hisHtmls)){
            $.get("${ctx}/webMessage/selectWebMessageUsers.htmls",
            {
                users_only_md5:'${currUserId}',
                master_only_md5:master_only_md5
            },
            function(data){
                var obj = eval(data);
                pushHTML(obj.entity,"master");
            });
        }
    }

以上2个方法的初衷,主要取决于是谁先点。用户界面点客服聊天,和客服界面点用户聊天。

//将获得的聊天记录布局到html中
    function pushHTML(list,obj){
        if("error" == list){
            hisHtmls = "暂无历史聊天记录";
        }else{
            list = eval(list);
            for(i=list.length-1;i>=0;i--){
                if(obj != "users"){
                    if(regNull(list[i].user_content)){
                        //管理员发送
                        hisHtmls += "<div class=\"leftd\">"+
                            "<div style=\"float:left;\">"+
                            "<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
                            "</div>"+
                            "<div class=\"speech left\" style=\"margin-right:61px;\">"+list[i].master_content+"</div>"+
                            "</div>";
                    }else{
                        //用户发送
                        hisHtmls += "<div class=\"rightd\">"+
                            "<div style=\"float:right;\">"+
                            "<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
                            "</div>"+
                            "<div class=\"speech right\" style=\"margin-right:61px;\">"+list[i].user_content+"</div>"+
                            "</div>";
                    }
                }else{
                    if(regNull(list[i].user_content)){
                        //管理员发送
                        hisHtmls += "<div class=\"rightd\">"+
                            "<div style=\"float:right;\">"+
                            "<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
                            "</div>"+
                            "<div class=\"speech right\" style=\"margin-right:61px;\">"+list[i].master_content+"</div>"+
                            "</div>";
                    }else{
                        //用户发送
                        hisHtmls += "<div class=\"leftd\">"+
                            "<div style=\"float:left;\">"+
                            "<img src=\"../img/20180917141606.png\" style=\"width:40px;height:40px;\"/>"+
                            "</div>"+
                            "<div class=\"speech left\" style=\"margin-right:61px;\">"+list[i].user_content+"</div>"+
                            "</div>";
                    }
                }
            }
        }
        $("#liaotian").append(hisHtmls);
        //该jquery是为了让滚动条一直居底部
        $('#liaotian').scrollTop($('#liaotian')[0].scrollHeight);
    }

<script type="text/javascript">
    /**初始化页面所加载的数据*/
    //获取会话列表
    findMsgUser();
</script>

<body>
    登录用户ID:
    <input type="text" id="login" value="${currUserId}" readonly="readonly"/> 目标ID:
    <input type="text" id="toUserId" value="" readonly="readonly"/>
    <input type="text" id="identity" value="${identity}" readonly="readonly"/></p>
    <div style="width:610px;height:500px;">
        <div id="liaotian" style="border: 1px solid red;width:400px;height:500px;overflow-x: hidden;overflow-y: auto;float:left;">
    
        </div>
        <div id="newMsgUser" style="border:1px solid red;width:200px;height:500px;float:right;overflow-x: hidden;overflow-y: auto;">
            
        </div>
    </div>
    </p>
    <div style="width:400px;height:50px">
        <div style="width:300px;height:49px;float: left;">
            <textarea id="sendMessage" rows="" cols=""
                style="width: 320px;height:49px"></textarea>
        </div>
        <div style="width:80px;height:49px;float:right;">
            <input type="button" id="push" value="发送"
                style="width:80px;height:49px;" οnclick="privateMessage()" />
        </div>
    </div>
</body>

<script src="${ctx}/rong/RongIMLib-2.3.3.min.js"></script>
<script src="//cdn.ronghub.com/RongEmoji-2.2.4.min.js"></script>
<script src="//cdn.ronghub.com/RongIMVoice-2.2.4.min.js"></script>
<script src="${ctx}/rong/init.js"></script>
<script src="${ctx}/js/jquery-2.1.4.min.js"></script>
<script src="${ctx}/common/common.js"></script>
<style type="text/css">
div.speech {
    margin: 10px 0;
    padding: 8px;
    table-layout: fixed;
    word-break: break-all;
    position: relative;
    background: -webkit-gradient(linear, 50% 0%, 50% 100%, from(#ffffff),
        color-stop(0.1, #ececec), color-stop(0.5, #dbdbdb),
        color-stop(0.9, #dcdcdc), to(#8c8c8c));
    border: 1px solid #989898;
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
}

div.speech:before {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    left: 15px;
    top: -20px;
    border: 10px solid;
    border-color: transparent transparent #989898 transparent;
}

div.speech:after {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    left: 17px;
    top: -16px;
    border: 8px solid;
    border-color: transparent transparent #ffffff transparent;
}

div.speech.right {
    box-shadow: -2px 2px 5px #CCC;
    margin-right: 10px;
    width: 75%;
    float: right;
    background: -webkit-gradient(linear, 50% 0%, 50% 100%, from(#e4ffa7),
        color-stop(0.1, #bced50), color-stop(0.4, #aed943),
        color-stop(0.8, #a7d143), to(#99BF40));
}

div.speech.right:before {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    top: 9px;
    bottom: auto;
    left: auto;
    right: -10px;
    border-width: 9px 0 9px 10px;
    border-color: transparent #989898;
}

div.speech.right:after {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    top: 10px;
    bottom: auto;
    left: auto;
    right: -8px;
    border-width: 8px 0 8px 9px;
    border-color: transparent #bced50;
}

div.speech.left {
    box-shadow: 2px 2px 2px #CCCCCC;
    margin-left: 10px;
    width: 75%;
    float: left;
    background: -webkit-gradient(linear, 50% 0%, 50% 100%, from(#ffffff),
        color-stop(0.1, #eae8e8), color-stop(0.4, #E3E3E3),
        color-stop(0.8, #DFDFDF), to(#D9D9D9));
}

div.speech.left:before {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    top: 9px;
    bottom: auto;
    left: -10px;
    border-width: 9px 10px 9px 0;
    border-color: transparent #989898;
}

div.speech.left:after {
    content: '';
    position: absolute;
    width: 0;
    height: 0;
    top: 10px;
    bottom: auto;
    left: -8px;
    border-width: 8px 9px 8px 0;
    border-color: transparent #eae8e8;
}

.leftimg {
    float: left;
    margin-top: 10px;
}

.rightimg {
    float: right;
    margin-top: 10px;
}

.leftd {
    clear: both;
    float: left;
}

.rightd {
    clear: both;
    float: right;
}

.clear {
    clear: both;
}

.speed .left {
    float: left;
}

.speed .right {
    float: right;
}
</style>
<script type="text/javascript">
    //记录常量
    var hisHtmls = "";
    var toUserId = "";
</script>

页面的样式不是很好看,讲究用用。

还有好几个功能。目前正在开发中,等开发好了之后在更新上来。

以上的功能,目前已完成聊天,会话列表,聊天记录等。但是聊天记录还想还没保存到本地数据库,

之后开发 聊天记录存,未读数量,是否在线。等功能。

等写完在更新吧。

希望以上一点小小的功能  能与大家一起学习,一起分享。

该文档的代码顺序我并没有去整理,我是一段截取一段注释来描述该功能。如果看官需要复制代码,请注意下html的顺序,

理论上,代码是没有问题。但是需要修改一些部分参数,因为我是连数据库的。所以你们自行创建的数据库表字段,需要放到该页面上来。替换了 即可正常聊天。

第二章链接:https://blog.csdn.net/qq_35243979/article/details/82982449

融云api开发Java后台客服聊天功能(一)相关推荐

  1. 前端uniapp集成融云IM,简单的客服聊天

    这里写自定义目录标题 uniapp接入融云 融云文档API说明文档链接(常规) 接入 需注意项 uniapp接入融云 接入的第一步,当然是先看融云的文档,uniapp是混合开发,在手机端测试没有问题, ...

  2. java微信多客服_微信多客服聊天功能怎么实现?

    原标题:微信多客服聊天功能怎么实现? 朋友小赵是很早的一批代购,微信号上添加了不少顾客.随着业务不断扩展,口碑越来越好,客户数量越来越多.经常有顾客在微信上咨询,日子久了,小赵就有点吃不消了.于是小赵 ...

  3. express-ws实现客服聊天功能

    express-ws实现webSocket通信 前言 最近要给自己写的项目中加一个客服聊天的功能.就是前端商城和后台管理系统通信.但是是两个不同的端口. 百度了一下就找到了webSocket. 什么是 ...

  4. javaIO模型-Socket实现一个简单的客服聊天功能的改造(二)

    功能改进-线程池 当然,先不考虑改端口合不合实际场景 我们想达到的流程是这样的: 再加上线程池,来在一个进程中启动多个服务端和多个客户端(当然因为控制台是唯一的,所以没办法模拟通信了). 话不多说,代 ...

  5. QQ客服聊天功能网页跳转只需要几行代码

    <html><head><meta charset="utf-8"></head><body><a target= ...

  6. uniapp 微信小程序使用button调用在线客服聊天功能

    亲测可用,若有疑问请私信 <button open-type="contact" style="border-radius: 0;display: flex;fle ...

  7. java在线客服系统源码 springboot客服聊天源码 网页客服源码 netty通信技术,java源码

    ava在线客服系统源码 springboot客服聊天源码 网页客服源码 netty通信技术,java源码 Java在线客服系统源码 企业网站客服聊天源码 网页客服源码 开发环境:Java + Spri ...

  8. JAVA毕业设计客服管理系统计算机源码+lw文档+系统+调试部署+数据库

    JAVA毕业设计客服管理系统计算机源码+lw文档+系统+调试部署+数据库 JAVA毕业设计客服管理系统计算机源码+lw文档+系统+调试部署+数据库 本源码技术栈: 项目架构:B/S架构 开发语言:Ja ...

  9. 微信公众平台开发之微客服

    微信公众平台开发之微客服是实现人工客服的重要手段.前面我们介绍如何添加自定义回复,当用户发送某个关键词给我们的平台的时候就能根据我们添加的关键词自动回复.但是这样我们不能把所有的词语都添加进去,有时候 ...

最新文章

  1. 2022-2028年中国网络直播行业深度调研及投资前景预测报告
  2. Proxool配置多数据源动态切换
  3. duilib 显示内存图片
  4. Fragment详解之四——管理Fragment(2)
  5. 第四范式成为金融信创生态实验室首个AI合作伙伴
  6. java将030A转换为方块_JAVA试题
  7. 在HTML中嵌入PHP代码,有以下几种方法,其中错误的是( )
  8. redis通过expire设置存活期注意问题
  9. 太形象了!什么是边缘计算?最有趣的解释没有之一!
  10. 移动互联网数据安全蓝皮报告(2021年)
  11. python编程入门教程100例_Python3入门经典100例(60-70)
  12. python搭建环境教程_python教程(一)·python环境搭建
  13. IntellJ IDEA神器使用技巧
  14. xp启用计算机共享打印机,Win7如何共享xp的打印机
  15. Edge 浏览器的收藏夹文档位置——最新版windows10和edge
  16. 经典论文复现|手把手带你复现ICCV 2017经典论文—PyraNet
  17. matlab画gds图,Matlab GDS流程.doc
  18. SLAM学习笔记(二十)LIO-SAM流程及代码详解(最全)
  19. 阿里云边缘云计算的技术和实践
  20. 求知若饥,虚心若愚----不错的演讲,与大家共勉

热门文章

  1. shell中的单引号、双引号、反引号
  2. 突发!Soul上市中止,因不正当竞争行为成被告,遭索赔410万美元
  3. cube-studio配置镜像仓库并执行jar
  4. 裸机win7系统安装
  5. 金立android在哪里设置密码,金立s5.5手机怎么设置锁屏密码 金立s5.5屏幕密码设置教程...
  6. DIY四周飞行器(小型无人机)附全部技术资料和设计文件
  7. 页面加载不出来的原因
  8. Silverlight+WCF 新手实例 象棋 棋子移动-规则[将、马、士、相、炮](八)
  9. html flex布局水平居中,CSS3 Flexbox轻松实现元素的水平居中和垂直居中
  10. 【转】常见植物油的致毒点