APICloud平台的融云2.0集成
融云2.0的官方文档地址:http://docs.apicloud.com/端API/开放SDK/rongCloud2
项目须要IM模块,最后还是选择了融云.在iOS原生开发中,融云sdk集成了聊天界面,给开发人员提供了非常大的便利,可是在apicloud平台上,因为开发人员应用IM的场景各异,需求不统一,所以官方没有将聊天界面集成到模块中.
因此我选择了AUI这套专门为apicloud提供的前端开发框架进行IM界面的搭建.AUI官方地址:http://www.auicss.com.
这套框架集成了非常多手机端的UI,效果不错,并且还在不断的更新中,大家最好还是尝试一下.我用过当中的几个,整体感觉还是不错的!
接下来,就详细的说一说RongYun集成的步骤了(本文会不断的更新,若发现不妥之处和须要改进的地方,能够给我留言,谢谢!)
一.准备工作
在集成融云2.0之前,首先要到融云官网上进行注冊,然后加入应用信息,而且生成两个測试用的targetId并记录下相应的token(这样的方法仅为測试使用) 融云的官网:http://www.rongcloud.cn
之后在API调试里面 生成userID相应的token,这些信息在初始化融云时会用到,
之后再次生成一个userID,并记录相应的token.这样,就相当于建立了两个用户,用户A和用户B,,之后便可实现用户A与用户B之间的通信了.
上述内容准备完之后,就要在自己的apicloud应用中加入融云2.0模块了. apicloud中的融云集成之前的准备在此略过,能够參照官方文档.
二.融云2.0的集成
在具体的介绍之前,先要说一说这个聊天界面使用的框架和模板.
1.doT.js (不熟悉的小伙伴能够參照这篇博客: http://www.cnblogs.com/kuikui/p/3505768.html)
2.AUI 前端UI框架(地址在上面给过了,非常有用,小伙伴们能够看一看).
3.UIChatBox, 文档地址: http://docs.apicloud.com/端API/界面布局/UIChatBox#m11
好了,有了这几个,就能够轻松的完毕一个简单的聊天界面的集成了!
1.融云2.0的初始化
首先要在config文件中填入一下代码
<feature name="rongCloud2">
<param name="appKey" value="这里填写在融云官网自己app相应的key" />
</feature>
再次初始化或者 connect 就会出错.
//1、RongY初始化
var rong = api.require('rongCloud2');
rong.init(function (ret, err) {
});
//2、进行监听
rong.setOnReceiveMessageListener(function (ret, err) {
});
//3、链接到RongY
rong.connect({
token: $api.getStorage("RongToken")
},
function (ret, err) {
if (ret.status == 'success') {
//实时监听收到的消息
} else {
}
});
2.聊天界面UI
<span style="font-size:14px;"><body> <!--//发送语音提示框-->
<div class="aui-toast" style="display:none" id="loading">
<div class="aui-toast-loading"></div>
<div class="aui-toast-content"></div>
</div>
<!--聊天页面-->
<div id="wrap" class="flex-wrap flex-vertical">
<div id="message-content2" style="margin-top: 10px"></div>
<div class="aui-content aui-content-padded" id="message-content">
<script id="message-content-template" type="text/x-dot-template"> {{for(var i=0;i<it.length ;i++){}} {{? it[i].tag=== 'TxtMsg'}}
<div class="{{=it[i].firstSendType}}" style="margin-top: 20px">
{{? it[i].messageDirection=== 'SEND'}}
<div class="aui-text-center history-date">{{=it[i].sentTime}}</div>
{{? ? it[i].messageDirection=== 'RECEIVE'}}
<div class="aui-text-center history-date">{{=it[i].receivedTime}}</div>
{{?}}
<div class="{{=it[i].secondSendType}}"><img src="../image/demo1.png"></div>
<div class="{{=it[i].thirdSendType}}">
<div class="{{=it[i].fourthSendType}}"></div>
<span id="txt">{{=it[i].content.text}}</span>
</div>
</div>
{{?}}
{{? it[i].tag === 'ImgMsg'}}
<div class="{{=it[i].firstSendType}}" style="margin-top: 20px">
{{? it[i].messageDirection=== 'SEND'}}
<div class="aui-text-center history-date">{{=it[i].sentTime}}</div>
{{?? it[i].messageDirection=== 'RECEIVE'}}
<div class="aui-text-center history-date">{{=it[i].receivedTime}}</div>
{{?}}
<div class="{{=it[i].secondSendType}}"><img src="../image/demo1.png"></div>
<div class="{{=it[i].thirdSendType}}">
<div class="{{=it[i].fourthSendType}}"></div>
<img class="lazy" id="image" style="width: 100px; height: 100px" ;
data-original="{{=it[i].content.imageUrl}}"
onclick="clickShowBigPic('{{=it[i].content.imageUrl}}')">
</div>
</div>
{{?}}
{{? it[i].tag === 'VcMsg'}}
<div class="{{=it[i].firstSendType}}" style="margin-top: 20px">
{{? it[i].messageDirection=== 'SEND'}}
<div class="aui-text-center history-date">{{=it[i].sentTime}}</div>
{{? ? it[i].messageDirection=== 'RECEIVE'}}
<div class="aui-text-center history-date">{{=it[i].receivedTime}}</div>
{{? }}
<div class="{{=it[i].secondSendType}}"><img src="../image/demo1.png"></div>
<div class="{{=it[i].thirdSendType}}">
<div class="{{=it[i].fourthSendType}}"></div> <div class="aui-chat-status"><i id="voice-length{{=it[i].messageId}}" class="">{{=it[i].content.duration}}"</i>
</div>
{{? it[i].content.duration <= '15'}}
<span style="width: {{=it[i].content.duration * 15}}px;height: 30px; border-radius: 5px; background: green"
onclick="playVoice('{{=it[i].messageId}}', '{{=it[i].</span><span style="font-family: Arial, Helvetica, sans-serif; font-size: 14px;">content</span><span style="font-family: Arial, Helvetica, sans-serif;">}}')"></span></span><span style="font-size:14px;">
{{? ? }}
<span style="width: 170px;height: 30px; border-radius: 5px; background: green"
onclick="playVoice('{{=it[i].messageId}}', '{{=it[i].content}}')"></span>
{{?}}
</div>
</div>
{{?}}
{{}}}
</script>
</div>
</div>
</body></span>
整个聊天界面的UI就是这些代码了,还是非常easy的吧~~当然了,这里仅仅实现了主要的功能,代码兴许会不断的更新.
3.JS部分
<span style="font-size: 18px;"> </span><span style="font-size:14px;">//发送消息
function sengTxtMsg(p) {
if (isConnetced) { var para;
var rong = api.require('rongCloud2');
rong.sendTextMessage({
conversationType: 'PRIVATE',
targetId: '13644978865',
text: p.msg,
extra: ''
}, function (ret, err) { // alert(JSON.stringify((ret)));
//这里要推断消息类型,最后设定消息标签.
if (ret.status == 'prepare') {
var tag;
if (ret.result.message.objectName == "RC:TxtMsg") {
tag = "TxtMsg";
} else if (ret.result.message.objectName == "RC:ImgMsg") {
tag = "ImgMsg";
} else if (ret.result.message.objectName == "RC:VcMsg") {
tag = "VcMsg";
} else if (ret.result.message.objectName == "RC:LBSMsg") {
tag = "LBSMsg";
} para = {
firstSendType: "aui-chat-sender",
secondSendType: "aui-chat-sender-avatar",
thirdSendType: "aui-chat-sender-cont",
fourthSendType: "aui-chat-right-triangle",
content: ret.result.message.content,
tag: tag,
//时间戳
sentTime: getTrueTime(ret.result.message.sentTime),
//发送类型
messageDirection: "SEND"
};
//这里我设置的每隔3分钟才会生成一个时间戳,假设没到三分钟时间为空,就显示不出来了
if (!timeTag) {
para.sentTime = "";
}
} else if (ret.status == 'success') {
//doT.js的拼接
msgObj.push(para);
var interText = doT.template($("#message-content-template").text());
$("#message-content2").html(interText(msgObj));
$("img.lazy").lazyload();
document.getElementsByTagName('BODY')[0].scrollTop = document.getElementsByTagName('BODY')[0].scrollHeight; //时间戳推断为false 不再发送
timeTag = false;
}
else if (ret.status == 'error')
api.toast({msg: err.code});
}
);
} else {
api.alert({
msg: "未连接到server"
});
}
}</span>
ok,再简单的说明一下:通过点击键盘发送button,获取到输入框的文本信息,将其作为參数传递到该方法中,通过该方法将消息发送到用户B.
//发送图片
function sendPictures(index) {
var type = "";
if (index == "0") {
type = 'album';
getPicture(type);
} else if (index == "1") {
type = 'camera';
getPicture(type);
} else {
getLocation();
}
} //获取图片
function getPicture(type) { var para;
api.getPicture({
sourceType: type,
encodingType: 'jpg',
mediaValue: 'pic',
destinationType: 'url',
allowEdit: false,
quality: 80,
// targetWidth: 100,
// targetHeight: 100,
saveToPhotoAlbum: false
}, function (ret, err) {
if (ret) { var para;
var rong = api.require('rongCloud2');
rong.sendImageMessage({
conversationType: 'PRIVATE',
targetId: '13644978865',
imagePath: ret.data,
extra: ''
}, function (ret, err) {
// alert(JSON.stringify((ret)));
if (ret.status == 'prepare') {
var tag;
if (ret.result.message.objectName == "RC:TxtMsg") {
tag = "TxtMsg";
} else if (ret.result.message.objectName == "RC:ImgMsg") {
tag = "ImgMsg";
} else if (ret.result.message.objectName == "RC:VcMsg") {
tag = "VcMsg";
} else if (ret.result.message.objectName == "RC:LBSMsg") {
tag = "LBSMsg";
} para = {
firstSendType: "aui-chat-sender",
secondSendType: "aui-chat-sender-avatar",
thirdSendType: "aui-chat-sender-cont",
fourthSendType: "aui-chat-right-triangle",
content: ret.result.message.content,
tag: tag,
//时间戳
sentTime: getTrueTime(ret.result.message.sentTime),
//发送类型
messageDirection: "SEND"
};
//推断时间
if (!timeTag) {
para.sentTime = "";
}
} else if (ret.status == 'progress') { }
// api.toast({msg: ret.result.progress});
else if (ret.status == 'success') { //时间戳推断为false 不再发送
timeTag = false;
msgObj.push(para); var interText = doT.template($("#message-content-template").text());
$("#message-content2").html(interText(msgObj));
$("img.lazy").lazyload();
document.getElementsByTagName('BODY')[0].scrollTop = document.getElementsByTagName('BODY')[0].scrollHeight;
} else if (ret.status == 'error') {
api.toast({msg: "请检查当前网络状态"});
}
}
);
} else {
alert(JSON.stringify(err));
}
});
}
//发送语音消息
function sendVoiceMsg(para) { var param;
var rong = api.require('rongCloud2');
rong.sendVoiceMessage({
conversationType: 'PRIVATE',
targetId: '13644978865',
voicePath: para.path,
duration: para.duration,
extra: ''
}, function (ret, err) {
// alert(JSON.stringify(ret));
if (ret.status == 'prepare') {
// api.toast({ msg: JSON.stringify(ret.result.message) }); var tag;
if (ret.result.message.objectName == "RC:TxtMsg") {
tag = "TxtMsg";
} else if (ret.result.message.objectName == "RC:ImgMsg") {
tag = "ImgMsg";
} else if (ret.result.message.objectName == "RC:VcMsg") {
tag = "VcMsg";
} else if (ret.result.message.objectName == "RC:LBSMsg") {
tag = "LBSMsg";
} param = {
firstSendType: "aui-chat-sender",
secondSendType: "aui-chat-sender-avatar",
thirdSendType: "aui-chat-sender-cont",
fourthSendType: "aui-chat-right-triangle",
content: ret.result.message.content,
tag: tag,
//时间戳
sentTime: getTrueTime(ret.result.message.sentTime),
//发送类型
messageDirection: "SEND"
};
//推断时间
if (!timeTag) {
param.sentTime = "";
} } else if (ret.status == 'success') {
//改变时间戳状态
timeTag = false; msgObj.push(param);
//// alert(JSON.stringify(msgObj));
alert(JSON.stringify(msgObj[msgObj.length - 1]));
var interText = doT.template($("#message-content-template").text());
$("#message-content2").html(interText(msgObj));
$("img.lazy").lazyload();
document.getElementsByTagName('BODY')[0].scrollTop = document.getElementsByTagName('BODY')[0].scrollHeight;
}
else if (ret.status == 'error') {
// api.toast({ msg: err.code });
}
}
);
}
</span>
上面就是我刚才发送的一连串语音消息了.
3.4 消息的接收
消息的接收,要用到 rong.setOnReceiveMessageListener这种方法.也就是这种方法会监听你收到的消息.详细代码例如以下
var rong = api.require('rongCloud2');
rong.setOnReceiveMessageListener(function (ret, err) {
// alert(JSON.stringify(ret));
var tag;
var para;
if (ret.result.message.objectName == "RC:TxtMsg") {
tag = "TxtMsg";
} else if (ret.result.message.objectName == "RC:ImgMsg") {
tag = "ImgMsg";
} else if (ret.result.message.objectName == "RC:VcMsg") {
tag = "VcMsg";
} else if (ret.result.message.objectName == "RC:LBSMsg") {
tag = "LBSMsg";
} para = {
firstSendType: "aui-chat-receiver",
secondSendType: "aui-chat-receiver-avatar",
thirdSendType: "aui-chat-receiver-cont",
fourthSendType: "aui-chat-left-triangle",
content: ret.result.message.content,
tag: tag,
receivedTime: getTrueTime(ret.result.message.receivedTime),
messageDirection: "RECEIVE"
};
if (!timeTag) {
para.receivedTime = "";
} msgObj.push(para);
var interText = doT.template($("#message-content-template").text());
$("#message-content2").html(interText(msgObj));
$("img.lazy").lazyload();
document.getElementsByTagName('BODY')[0].scrollTop = document.getElementsByTagName('BODY')[0].scrollHeight;
//时间戳状态
timeTag = false; });
上面就是三条通过iPhone模拟器发送的消息,一条语音消息,一条图片消息,一天文字消息.
3.4 获取历史消息
获取历史消息也用相应的方法.并且这些消息是存在本地的,所以获取非常方便
//获取近期聊天信息
function getRecentConverMsg() { // alert(num);
var rong = api.require('rongCloud2');
//先获取之前的聊天记录
rong.getHistoryMessages({
conversationType: 'PRIVATE',
targetId: '13644978865',
oldestMessageId: -1,
count: 500
}, function (ret, err) { // api.refreshHeaderLoadDone();
var arr = [];
arr = ret.result;
// alert(JSON.stringify(arr));
//记录最早的时间戳
$api.setStorage('time', arr[arr.length - 1].receivedTime);
for (var i = arr.length - 1; i >= 0; i--) {
if (arr[i].messageDirection == "SEND") {
arr[i].firstSendType = "aui-chat-sender";
arr[i].secondSendType = "aui-chat-sender-avatar";
arr[i].thirdSendType = "aui-chat-sender-cont";
arr[i].fourthSendType = "aui-chat-right-triangle";
} else {
arr[i].firstSendType = "aui-chat-receiver";
arr[i].secondSendType = "aui-chat-receiver-avatar";
arr[i].thirdSendType = "aui-chat-receiver-cont";
arr[i].fourthSendType = "aui-chat-left-triangle";
} if (arr[i].objectName == "RC:TxtMsg") {
arr[i].tag = "TxtMsg";
} else if (arr[i].objectName == "RC:ImgMsg") {
arr[i].tag = "ImgMsg";
} else if (arr[i].objectName == "RC:VcMsg") {
arr[i].tag = "VcMsg";
} else if (arr[i].objectName == "RC:LBSMsg") { } //假设时间间隔大于五分钟 加上时间戳
if (arr[i].receivedTime - $api.getStorage("time") >= 180000) {
// alert("yes");
$api.setStorage('time', arr[i].receivedTime);
arr[i].receivedTime = getTrueTime(arr[i].receivedTime);
arr[i].sentTime = getTrueTime(arr[i].sentTime);
} else {
arr[i].receivedTime = "";
arr[i].sentTime = "";
} msgObj.push(arr[i]);
}
var interText = doT.template($("#message-content-template").text());
$("#message-content2").prepend(interText(msgObj));
$("img.lazy").lazyload();
document.getElementsByTagName('BODY')[0].scrollTop = document.getElementsByTagName('BODY')[0].scrollHeight; }); }
这样,我能够获取到之前3.31的聊天记录.
到这里,最主要的功能介绍完了,兴许的功能还有非常多,比方图片的查看,保存图片到本地,语音的播放等等,都是小问题了,这些代码就不放上来了.
本文会不断更新,欢希望大家提出很多其它的意见,一起进步!我的微信656593047,能够加我一起交流!!
聊天页面代码地址:https://github.com/ZCLegendary/APICloudRongYun
APICloud平台的融云2.0集成的更多相关文章
- iOS开发融云即时通讯集成详细步骤
1.融云即时通讯iOS SDK下载地址 http://rongcloud.cn/downloads 选择iOS SDK下载 2.进行应用开发之前,需要先在融云开发者平台创建应用,如果您已经注 ...
- 融云参加RTC实时互联网大会 现场集成IM SDK
9月21至22日,由全球实时云服务商声网Agora.io主办的RTC2017实时互联网大会在北京万豪酒店成功举办.作为亚洲最权威的RTC实时通信行业技术盛会,会议吸引了来自全球上千名开发者参加,Goo ...
- APICloud数据云3.0 -- 让后端业务更简单
近年来,各类移动端应用层出不穷,app.小程序已成为企业业务数字化的必然选择,围绕互联网产品的技术创新与开发者生态,正在历经行业发展的又一次革新. APICloud作为国内领先的移动应用开发平台,一直 ...
- iOS:融云即时通讯快速集成
一.介绍 即时通讯在众多社交软件.生活软件以及教育软件中已经是必备的功能了,在当前国内,即时通讯SDK做的比较不错的有那么几家,例如环信SDK.融云SDK...,这两家做的都很不错,各有千秋吧,要是真 ...
- apicloud+融云实现即时通讯
请尊重作者的辛勤劳动!!! 使用apicloud开发已经快2个月了,起初的目的就是为了实现安卓和苹果的兼容,属于一个试验项目,究竟apicloud是否能够满足公司的要求?最 终看来还是不错的,使用ap ...
- android7.0以上使用融云即使通讯的坑
一.连接服务器不走connect()方法 在android6.0以下,在使用融云sdk时,直接将依赖库引入到项目中即可.但是在7.0及以上时,直接应用会发现消息一直发送不出去,错误提示为dlopen ...
- ios开发之 -- 5分钟集成融云的客服功能
最近项目中遇到了客服的功能,首先想到的就是使用融云的功能,因为以前做的即时通讯的项目,用的都是融云的sdk,花了点时间研究了下,希望能帮到大家! 废话不多说,步骤如下: 一.申请融云账号 二.创建应用 ...
- 融云消息接口apicloud
融云提供消息发送服务,支持个人消息,群消息,讨论组,聊天室消息, 以下是它涉及到的接口. 初始化,连接之后,可以使用. <!DOCTYPE html> <html> <h ...
- APICloud框架——融云+UIChatTools实现即时通讯聊天
今天完成了公司app的聊天界面的收发消息功能,结合融云2和UIChatTools模块实现,只是实现了基本功能,好多细节还没有实现,废话不多说,上代码 输入框页面(win) 先引入所需模块 // 融云模 ...
随机推荐
- CAD参数绘制填充(网页版)
填充是CAD图纸中不可或缺的对象,在机械设计行业,常常需要将零部件剖开,以表现其内部的细节,而这些被剖开的截面会用填充来表示:在工程设计行业,一些特殊的材料或地形,也会用填充来表示. js中实现代码说 ...
- 解决webstorm中vue语法没有提示
首先看看webstrom内置的vue插件,打上勾,没有这个选项就要自己去下载插件了 如果插件还是没有语法提示,可以用下面的方法,自己添加语法进去搜索 unknown HTML tag attribut ...
- ubuntu apt-update NO_PUBKEY 40976EAF437D05B5 NO_PUBKEY 3B4FE6ACC0B21F32
Fetched 28.1 MB in 11s (2344 kB/s) W: GPG error: http://archive.canonical.com xenial Release: The fo ...
- [css或js控制图片自适应]
[css或js控制图片自适应]图片自动适应大小是一个非常常用的功能,在进行制作的时候为了防止图片撑开容器而对图片的尺寸进行必要的控制,我们可不可以用CSS控制图片使它自适应大小呢?此个人博客想到了一个 ...
- 关于OpenMP的归约操作reduction
这里提一个重要的点 像这样 ; void ff() { sum += 0.5; } //main() #pragma omp parallel for reduction(+:sum) ; i < ...
- [Usaco2009 Nov]lights(高斯消元)
luogu 点灯游戏应该很多人都在小时候頽过吧 反正我直到现在也不会 很明显一个灯最多只需要点一次 然后高斯消元 解完肯定剩自由元(就是那些全是0的行) 然后这些都爆搜 由于剩下的自由元不会太多 所以 ...
- [Python3网络爬虫开发实战] 7.2-Splash的使用
Splash是一个JavaScript渲染服务,是一个带有HTTP API的轻量级浏览器,同时它对接了Python中的Twisted和QT库.利用它,我们同样可以实现动态渲染页面的抓取. 1. 功能介 ...
- 零基础入门学习Python(14)--字符串:各种奇葩的内置方法
前言 这节课我们回过头来,再谈一下字符串,或许我们现在再来谈字符串,有些朋友可能觉得没必要了,甚至有些朋友就会觉得,不就是字符串吗,哥闭着眼也能写出来,那其实关于字符串还有很多你不知道的秘密哦.由于字 ...
- 安装配置elasticsearch、安装elasticsearch-analysis-ik插件、mysql导入数据到elasticsearch、安装yii2-elasticsearch及使用
一.安装elasticsearch 获取elasticsearch的rpm:wget https://download.elastic.co/elasticsearch/release/org/ela ...
- buf.slice()
buf.slice([start[, end]]) start {Number} 默认:0 end {Number} 默认:buffer.length 返回:{Buffer} 返回一个指向相同原始内存 ...