apicloud+融云实现即时通讯

  请尊重作者的辛勤劳动!!!

使用apicloud开发已经快2个月了,起初的目的就是为了实现安卓和苹果的兼容,属于一个试验项目,究竟apicloud是否能够满足公司的要求?最 终看来还是不错的,使用apicloud+融云实现了类似微信即时通讯的功能。看到有很多后来的人依然在这块挣扎,我就把自己的实现思路和成果分享出来和 大家一起交流一下,我也是第一次做手机开发,有很多经验不足的地方,希望大家能够直接指出来,我也不断完善自己的产品。
    这次没有使用本地数据库,所有数据都是从融云和服务器获取,会影响性能,下一步会把数据本地化处理,再将优化后的代码和大家交流。
    具体实现的思路,说的可能会有些混乱,希望大家能谅解~
    一、功能说明:
    1. 登录功能:类似微信,登录后记住当前人账号和密码,记在了Storage里,可能会有安全性问题,想在第二版优化时保存在数据库中;
    2. 通讯录功能:类似微信,包括群组及好友列表
    3. 历史会话列表:类似微信,包括群组及个人的历史会话列表
    4. 发送内容:包括文本、语音和图片
    二、使用的模块
        包括:fs、imageBrowser、bubbleMenu、listContact、UIMediaScanner、rongCloud、UIChatBox
    三、实现思路:
    PS:这里借鉴了 “流浪男” 的一篇文章,感谢他的对我实现思路的重大启发,原文:http://community.apicloud.com/bbs/forum.php?mod=viewthread&tid=8715
           使用论坛中的aui.css样式
            感谢技术客服  技术支持-M 的辛勤帮助
            感谢  吴勇  兄弟的帮助
    1.  登录操作,登录时访问服务器(自己的云服务器)获取token,服务器使用的是java的sdk获取token,组装token和人员的所有信息json返回到app,保存在storage里,后期会存到本地数据库中;
    2. 主界面,包括4个菜单,分别为会话历史页面、通讯录页面、应用页面和个人设置页面,所有的和融云相关的业务逻辑都在hh_index_window里面初始化,其他页面获取数据时,都是采取监听模式获取数据;
    3. 会话历史页面:hh_index_window.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport -->
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 -->
<meta name="format-detection" content="telephone=no"/>
<title>会话列表</title>
<link rel="stylesheet" type="text/css" href="../../css/aui.css" />
<style>
.span_name {
width: 20%;
/*font-size: 18px;*/
/*text-align: center;*/
display: inline-block;
/*word-break: keep-all;*/
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
</head>
<body>
<!--<div class="aui-content"><input type="button" value="为了测试,点击这里清空会话" onclick="clearConversations();"/>-->
<ul class="aui-user-view">
<!--<li class="aui-user-view-cell aui-img" onclick="openNewsList();">
<img class="aui-img-object aui-pull-left" src="../../image/person/demo1.png">
<div class="aui-img-body">
<span>系统消息1<em>10:22</em></span>
<p class=‘aui-ellipsis-1‘>
理想家校通上线啦~~~
</p>
</div>-->
<!--<div id="notify" style="height:0px;">
<div class="circle">
<p id="messages" class="circle_p"></p>
</div>
</div>-->
<!--</li>-->
<!--会话列表-->
<div id="hhlist_div"></div>
<script type="text/html" id="hhlist_script">
<% if(result.length == 0){ %>
<div
style="text-align:center;color:#666;"><span>您还没有会话记录,快去找小伙伴们聊天
吧~~</span></div>
<% }else{ %>
<%for(var i=0; i<result.length; i++) {%>

<li id="<%=result[i].targetId %>"
alt="<%=result[i].conversationType %>" class="aui-user-view-cell aui-img" onclick="openHhList(‘<%=result[i].targetId
%>‘,‘<%=result[i].latestMessageId
%>‘,‘<%=result[i].person_name
%>‘,‘<%=result[i].conversationType %>‘,‘hh_index‘);">
<img class="aui-img-object aui-pull-left" src="<%=result[i].avatar_url %>">
<div class="aui-img-body">
<span><span
class="span_name"><%=result[i].person_name
%></span><em><%=g_time.getTime(result[i].receivedTime,1)
%></em></span>
<% if(result[i].objectName == ‘RC:VcMsg‘) { %>
<p class=‘aui-ellipsis-1‘>[语音]</p>
<% } %>
<% if(result[i].objectName == ‘RC:TxtMsg‘) { %>
<p class=‘aui-ellipsis-1‘><%=result[i].latestMessage.text %></p>
<% } %>
<% if(result[i].objectName == ‘RC:ImgMsg‘) { %>
<p class=‘aui-ellipsis-1‘>[图片]</p>
<% } %>
</div>
<% if(result[i].unreadMessageCount > 0) { %>
<div style="height:0px;">
<div class="circle">
<p class="circle_p"><%=result[i].unreadMessageCount %></p>
<input type="hidden" class="unread_count" value="<%=result[i].unreadMessageCount %>"/>
</div>
</div>
<% } %>
</li>
<%}%>
<% } %>

</script>
</ul>
<!--</div>-->

<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../script/template.js"></script>
<script type="text/javascript" src="../../script/date.js"></script>
<!-- 长按控件 周枫 2015.08.05 -->
<script type="text/javascript" src="../../script/hammer.min.js"></script>
<script type="text/javascript" src="../../script/base_config.js"></script>
<script type="text/javascript" src="../../script/huihua/hh_index_window.js"></script>
</body>
</html>

/*
* 把所有的融云类的处理全部放在消息列表页,然后通过APICloud的api.sendEvent和api.addEventListener 来处理融云的一些事件。
记住除了消息列表页其他页面不要做融云的任何链接处理
*/
//定义融云
var rong;
//内容高度
var rect_h;
//header高度
var header_h;

apiready = function() {
api.showProgress({
title : ‘加载中...‘,
modal : false
});
rect_h = api.pageParam.rect_h;
header_h = api.pageParam.header_h;

//加载融云模块
rong = api.require(‘rongCloud‘);
//融云初始化
rongCloud();

//监听来自会话页面发送消息的事件
api.addEventListener({
name : ‘sendMessage‘
}, function(ret) {
if (ret && ret.value) {
var value = ret.value;
switch(value.type) {
case ‘text‘:
sendMessage(‘‘ + value.type + ‘‘, ‘‘ + value.targetId + ‘‘, ‘‘ +
value.content + ‘‘, ‘‘ + value.extra + ‘‘, ‘‘ + value.conversationType +
‘‘);
break;
case ‘pic‘:
//判断是照相还是选择,选择是数组,照相是一个
switch(value.pic_source) {
case ‘camera‘:
sendPicture(‘‘ + value.targetId + ‘‘, ‘‘ + value.imgSrc + ‘‘, ‘‘ + value.extra + ‘‘, ‘‘ + value.conversationType + ‘‘);
break;
case ‘album‘:
// alert(JSON.stringify(value));
var img_list = value.img_list;
for (var i = 0; i < img_list.length; i++) {
// alert(value.img_list.image_list[i].path+‘123123‘);
//图片真实地址
var img_temp = img_list[i].path;
var img_url;
//文件后缀名,如:png,jpg, mp4
var suffix = img_list[i].suffix;
var obj_scan = api.require(‘UIMediaScanner‘);
if (api.systemType == ‘ios‘) {
//虚拟路径转真实路径
obj_scan.transPath({
path : img_temp
}, function(ret) {
//发送图片格式
if (suffix == ‘png‘ || suffix == ‘jpg‘) {
sendPicture(‘‘ + value.targetId + ‘‘, ‘‘ + ret.path + ‘‘, ‘‘ + value.extra + ‘‘, ‘‘ + value.conversationType + ‘‘);
}
});
} else if (api.systemType = "android") {
// api.alert({
// msg:img_temp
// },function(ret,err){
// //coding...
// });
//发送图片格式
if (suffix == ‘png‘ || suffix == ‘jpg‘) {
sendPicture(‘‘ + value.targetId + ‘‘, ‘‘ + img_temp + ‘‘, ‘‘ + value.extra + ‘‘, ‘‘ + value.conversationType + ‘‘);
}
}

}
break;
}
break;
case ‘voi‘:
sendVoice(‘‘ + value.targetId + ‘‘, ‘‘ + value.voicePath + ‘‘, ‘‘ +
value.duration + ‘‘, ‘‘ + value.extra + ‘‘, ‘‘ + value.conversationType
+ ‘‘);
break;
}
}
});

//监听来自会话页面获取历史会话的事件
api.addEventListener({
name : ‘getHistory‘
}, function(ret) {
if (ret && ret.value) {
var value = ret.value;
getHistoryMessagesById(value.type, value.target_id, value.old_msg_id, value.msg_count);
}
});

//监听来自通讯录页面获取最新会话id的事件
api.addEventListener({
name : ‘getOldMessageId‘
}, function(ret) {
if (ret && ret.value) {
var value = ret.value;
getLatestMessagesById(value.conver_type, value.target_id, value.count, function(mes_list) {
var old_msg_id = -1;
if (getJsonObjLength(mes_list) != 0) {
old_msg_id = mes_list[0].messageId;
}
//发送target_id获取最新会话id
api.sendEvent({
name : ‘setOldMessageId‘,
extra : {
old_msg_id : old_msg_id
}
});
});

}
});

//监听来注销页面的事件
api.addEventListener({
name : ‘logout‘
}, function(ret) {
rong.disconnect(false);
});

//系统消息未读使用
// var messages = Math.floor((Math.random()*10)+1);
// document.getElementById("messages").innerHTML = messages;
}
/*
* 打开会话页面
* 周枫
* 2015-08-03
*/
function openHhList(target_id, old_msg_id, person_name, conver_type, h_from) {
//清除未读信息
cleanMsg(target_id, conver_type);
getCoversationList();
//如果是群组,则获取群组人员姓名json
if (conver_type == "GROUP") {
getGroupInfoById(target_id);
}

api.openWin({
name : ‘hh_chat_window‘,
url : ‘hh_chat_window.html‘,
bounces : true,
animation : ‘push‘,
delay : 1,
scrollToTop : true,
pageParam : {
‘targetId‘ : target_id,
‘old_msg_id‘ : old_msg_id + 1,
‘conver_type‘ : conver_type,
‘person_name‘ : person_name,
‘header_h‘ : header_h,
‘conver_type‘ : conver_type,
‘h_from‘ : h_from
},
rect : {
x : 0,
y : ‘auto‘,
w : ‘auto‘,
h : ‘auto‘
}
});
$api.addEvt($api.byId(‘back‘), ‘click‘, function() {
api.closeWin();
});
// });
}

/**
* 打开消息列表页面
* 周枫
* 2015.08.17
*/
function openNewsList() {
api.openWin({
name : ‘xx_index_window‘,
url : ‘xx_index_window.html‘,
bounces : true,
animation : ‘push‘,
delay : 1,
scrollToTop : true,
pageParam : {
‘header_h‘ : header_h
},
rect : {
x : 0,
y : ‘auto‘,
w : ‘auto‘,
h : ‘auto‘
}
});
}

/*
* 融云初始化
* 周枫
* 2015-08-03
*/
function rongCloud() {
var token = $api.getStorage(‘mytoken‘);
//融云初始化
rong.init(function(ret, err) {
if (ret.status == "success") {
api.execScript({
name : ‘index‘,
script : ‘setTitle("会话");‘
});
} else {
api.execScript({
name : ‘index‘,
// frameName : ‘hh_index‘,
script : ‘setTitle("连接失败");‘
});
}
});
//监听新消息
receiveMessageListener();
//连接
rong.connect({
token : ‘‘ + token + ‘‘
}, function(ret, err) {
if (ret.status == ‘success‘) {
//清空所有会话
// clearConversations();
//消息列表
getCoversationList();
//初始化当前人员群组信息
// initPersonGroup();
// quitGroup();
} else {
var err_code = err.code;
switch(err_code) {
case "-1":
api.toast({
msg : "对不起,客户端发生未知错误!",
location : ‘middle‘
});
break;
case "2002":
api.toast({
msg : "对不起,客户端数据包不完整,请求数据包有缺失!",
location : ‘middle‘
});
break;
case "2003":
api.toast({
msg : "对不起,服务器不可用!",
location : ‘middle‘
});
break;
case "2004":
api.toast({
msg : "对不起,请重新向身份认证服务器获取 Token!",
location : ‘middle‘
});
break;
case "2005":
api.toast({
msg : "对不起,可能是错误的 App Key,或者 App Key 被服务器积极拒绝!",
location : ‘middle‘
});
break;
case "2006":
api.toast({
msg : "对不起,服务端数据库错误!",
location : ‘middle‘
});
break;
case "5004":
api.toast({
msg : "对不起,服务器超时!",
location : ‘middle‘
});
break;
case "-10000":
api.toast({
msg : "对不起,未调用 init 方法进行初始化!",
location : ‘middle‘
});
break;
case "-10002":
api.toast({
msg : "对不起,输入参数错误!",
location : ‘middle‘
});
break;
}
}
});
}

/*
* 监听新消息
当有新消息传来时,利用sendEvent发出一个事件,同时传递消息内容,可以在会话页面进行一次监听接收
* 周枫
* 2015-08-03
*/
function receiveMessageListener() {
rong.setOnReceiveMessageListener(function(ret, err) {
// api.alert({
// msg:JSON.stringify(ret)
// },function(ret,err){
// //coding...
// });
if (ret.status == "success") {
//发送事件
api.sendEvent({
name : ‘getNewMessage‘,
extra : {
data : ret.result.message
}
})
// cleanMsg(ret.result.message.targetId,ret.result.message.conversationType);
getCoversationList();
}
})
}

/*
* 获取会话消息列表
* 周枫
* 2015-08-03
*/
function getCoversationList() {
//消息列表
rong.getConversationList(function(ret, err) {
if (ret.status == ‘success‘) {
sendConListReJson(ret, function(list_json) {
beforeRender(list_json);
// api.alert({
// msg:JSON.stringify(list_json)
// });

var html_type = template.render(‘hhlist_script‘, list_json);
document.getElementById(‘hhlist_div‘).innerHTML = html_type;
api.hideProgress();
//未读总条数,显示在APP右上角
var unread_sum = 0;
var unread_arr = $api.domAll(‘.unread_count‘);
for (var i = 0; i < unread_arr.length; i++) {
var unread_count = parseInt($api.val(unread_arr[i]));
unread_sum = unread_sum + unread_count;
}
//设置应用图标右上角数字,支持所有iOS手机,以及部分Android手机,如小米和三星的某些型号
api.setAppIconBadge({
badge : unread_sum
});

var aui_img = $api.domAll(‘.aui-user-view-cell‘);
//如果之前有系统消息,需要改成从1开始循环,去掉系统消息
for (var i = 0; i < aui_img.length; i++) {
(function(i) {
var id = $api.attr(aui_img[i], "id");
//长按删除,3秒
var myHanmer = new Hammer($api.byId(id));
myHanmer.on("press", function(e) {
api.confirm({
title : "提示",
msg : "确认删除当前会话吗?",
buttons : ["取消", "确定"]
}, function(ret, err) {
if (1 == ret.buttonIndex) {
return;
} else {
//删除会话
clearMessageById($api.attr(myHanmer.input.target, ‘id‘), $api.attr(myHanmer.input.target, ‘alt‘));
}
});
// alert($api.attr(myHanmer.input.target,‘id‘));
});
})(i);
}
});
} else {
var errJson = JSON.stringify(err);
// api.alert({
// msg : "err=" + errJson
// });
}
});
}

/**
* 获取某一会话的最新消息记录
*/
function getLatestMessagesById(conver_type, target_id, count, callback) {
rong.getLatestMessages({
conversationType : conver_type,
targetId : target_id + ‘‘,
count : parseInt(count)
}, function(ret, err) {
if (ret.status == "success") {
callback(ret.result);
} else {
api.alert({
msg : ‘获取某一会话的最新消息记录失败‘
});
}
})
}

/**
* 获取历史聊天记录
* 周枫
* 2015.08.20
*/
function getHistoryMessagesById(conver_type, target_id, old_msg_id, msg_count) {
rong.getHistoryMessages({
conversationType : conver_type,
targetId : target_id,
oldestMessageId : parseInt(old_msg_id),
count : msg_count
}, function(ret, err) {
if (ret.status == ‘success‘) {
// alert(‘222:‘ + JSON.stringify(ret.result));
api.sendEvent({
name : ‘setHistory‘,
extra : {
data : ret.result
}
});
} else {
api.alert({
msg : ‘对不起,获取历史会话信息失败‘
});
}
})
}

/*
*发送消息的函数
注意要放在消息列表页,不要放在会话页面
在会话页面利用sendEvent发出一个发送消息的事件,在消息列表页监听
* 周枫
* 2015-08-03
*/
function sendMessage(type, targetId, content, extra, conversationType) {
// api.alert({
// msg: ‘type:‘+type+‘,targetId:‘+targetId+‘,content:‘+content+‘,conversationType:‘+conversationType
// },function(ret,err){
// //coding...
// });
rong.sendTextMessage({
conversationType : ‘‘ + conversationType + ‘‘,
targetId : ‘‘ + targetId + ‘‘,
text : ‘‘ + content + ‘‘,
extra : ‘‘ + extra + ‘‘
}, function(ret, err) {
if (ret.status == ‘prepare‘) {
//单聊准备发送,向会话页面发送正在发送消息事件
api.sendEvent({
name : ‘insertSendMessage‘,
extra : {
data : ret.result
}
})
//清除未读信息
cleanMsg(ret.result.message.targetId, conversationType);
} else if (ret.status == ‘success‘) {
//成功后处理
getCoversationList();
} else if (ret.status == ‘error‘) {
//失败
api.alert({
msg : ‘发送信息失败:‘ + err.msg
});
}
});
}

/**
* 发送图片消息
* 周枫
* 2015.08.11
* @param {Object} sendMsg
*/
function sendPicture(target_id, img_url, extra, conversationType) {
// api.alert({
// msg : ‘img_url:‘ + img_url + ‘,target_id:‘ + target_id
// }, function(ret, err) {
// //coding...
// });
rong.sendImageMessage({
conversationType : conversationType,
targetId : target_id,
imagePath : img_url,
extra : extra
}, function(ret, err) {
if (ret.status == ‘prepare‘) {
//单聊准备发送,向会话页面发送正在发送消息事件
api.sendEvent({
name : ‘insertSendMessage‘,
extra : {
data : ret.result
}
})
//清除未读信息
cleanMsg(ret.result.message.targetId, conversationType);
} else if (ret.status == ‘progress‘) {

} else if (ret.status == ‘success‘) {

} else if (ret.status == ‘error‘) {
var err_code = err.code;
switch(err_code) {
case -2:
api.alert({
msg : ‘对不起,图片发送失败‘
});
break;
case -1:
api.alert({
msg : ‘对不起,图片发送失败,未知错误‘
});
break;
case 3001:
api.alert({
msg : ‘对不起,图片发送失败,服务器超时‘
});
break;
case 405:
api.alert({
msg : ‘对不起,图片发送失败,您在黑名单中‘
});
break;
case -10000:
api.alert({
msg : ‘对不起,图片发送失败,未调用 init 方法进行初始化‘
});
break;
case -10001:
api.alert({
msg : ‘对不起,图片发送失败,未调用 connect 方法进行连接‘
});
break;
case -10002:
api.alert({
msg : ‘对不起,图片发送失败,输入参数错误‘
});
break;
}
}
});
}

/*
* 发送语音消息
* 周枫
* 2015.08.12
*
*/
function sendVoice(target_id, voicePath, duration, extra, conversationType) {
rong.sendVoiceMessage({
conversationType : conversationType,
targetId : target_id,
voicePath : voicePath,
duration : parseInt(duration),
extra : extra
}, function(ret, err) {
if (ret.status == ‘prepare‘) {
//单聊准备发送,向会话页面发送正在发送语音事件
api.sendEvent({
name : ‘insertSendMessage‘,
extra : {
data : ret.result
}
})
//清除未读信息
cleanMsg(target_id, conversationType);
} else if (ret.status == ‘success‘) {

} else if (ret.status == ‘error‘) {
var err_code = err.code;
switch(err_code) {
case -2:
api.alert({
msg : ‘对不起,语音发送失败‘
});
break;
case -1:
api.alert({
msg : ‘对不起,图片发送失败,未知错误‘
});
break;
case 3001:
api.alert({
msg : ‘对不起,图片发送失败,服务器超时‘
});
break;
case 405:
api.alert({
msg : ‘对不起,图片发送失败,您在黑名单中‘
});
break;
case -10000:
api.alert({
msg : ‘对不起,图片发送失败,未调用 init 方法进行初始化‘
});
break;
case -10001:
api.alert({
msg : ‘对不起,图片发送失败,未调用 connect 方法进行连接‘
});
break;
case -10002:
api.alert({
msg : ‘对不起,图片发送失败,输入参数错误‘
});
break;
}
}
});
}

/*
* 发送会话历史列表返回增加头像和姓名和时间的json
* 周枫
* 2015-08-05
*/
function sendConListReJson(con_list, callback) {
api.ajax({
url : BASE_URL_ACTION + ‘/rongcloud/getConListReList‘,
method : ‘post‘,
dataType : ‘json‘,
data : {
values : {
"con_list" : con_list,
"ip_addr" : BASE_SERVER_IP,
"app_type" : BASE_APP_TYPE
}
}
}, function(ret, err) {
if (ret) {
if (ret.status == ‘success‘) {
$api.setStorage(‘hh_index_list‘, ret.result);
callback(ret);
} else {
api.alert({
msg : ‘对不起,获取会话列表失败‘
});
}

}
});
}

/*
* 清空某一会话的所有聊天消息记录
* 周枫
* 2015-08-05
*/
function clearMessageById(user_id, conver_type) {
//首先移除会话列表
rong.removeConversation({
conversationType : conver_type,
targetId : user_id
}, function(ret, err) {
if (ret.status == ‘success‘) {
//再真实删除聊天记录
rong.clearMessages({
conversationType : conver_type,
targetId : user_id
}, function(ret, err) {
if (ret.status == ‘success‘) {
// api.toast({
// msg : ‘操作成功‘,
// duration : 1000,
// location : ‘middle‘
// });
//重新获取会话列表
getCoversationList();
}
});
}
})
}

/*
* 清空所有会话及会话消息
* 周枫
* 2015-08-05
*/
function clearConversations() {
rong.clearConversations({
conversationTypes : [‘PRIVATE‘, ‘GROUP‘, ‘SYSTEM‘]
}, function(ret, err) {
if (ret.status == ‘success‘) {

} else {
api.alert({
msg : ‘对不起,删除失败‘
});
}
//重新获取会话列表
getCoversationList();
})
}

/*
* 清除未读信息红点和条数
* 周枫
* 2015-08-03
*/
function cleanMsg(target_id, conver_type) {
rong.getHistoryMessages({
conversationType : conver_type,
targetId : target_id,
oldestMessageId : -1,
count : 1
}, function(ret, err) {
if (ret.status != "success") {
api.alert({
msg : ‘清除未读信息失败‘
});
}
})
}

/**
* 废弃,因为融云初始化有问题
* 同步当前用户所属的群组信息到融云服务器
* PS:由于apicloud的参数问题,所以暂时启用了
* 周枫
* 2015.08.24
*/
function initPersonGroup() {
var person_id = $api.getStorage(‘person_id‘);
var identity_id = $api.getStorage(‘identity‘);
var ip_addr = BASE_SERVER_IP;
//获取当前人员群组信息
api.ajax({
url : BASE_URL_ACTION + ‘/group/queryMyGroupForApp?person_id=‘ +
person_id + ‘&identity_id=‘ + identity_id + ‘&ip_addr=‘ +
ip_addr,
method : ‘get‘,
dataType : ‘text‘
}, function(ret, err) {
var p_group = eval(‘(‘ + ret + ‘)‘);
if (p_group.success == true) {
//同步当前用户所属的群组信息到融云服务器
rong.syncGroup({
groups :
// p_group.groups
[{
// groupId : ‘975‘,
// groupName : ‘张福才‘,
// portraitUri : ‘../../image/person/group.png‘
id : ‘975‘,
name : ‘张福才‘,
portraitUrl : ‘../../image/person/group.png‘
}, {
// groupId : ‘976‘,
// groupName : ‘张福才2‘,
// portraitUri : ‘../../image/person/group.png‘
id : ‘976‘,
name : ‘张福才2‘,
portraitUrl : ‘../../image/person/group.png‘
}]
}, function(ret, err) {
api.toast({
msg : JSON.stringify(ret)
});
})
} else {
api.alert({
msg : ‘初始化群组信息失败:‘ + p_group.info
});
}
});
}

function beforeRender(data) {
var g_time = new getTimeTemplate();
//g_time为想在template的标签中执行的函数
data.g_time = g_time;
}

这个页面主要包括加载融云的初始化和各种操作,所有函数都有注释就不解释了,总之,其他页面使用数据时都是使用监听获取数据的
    4. 会话页面,包括hh_chat_window.html和hh_chat_frame.html两个页面,相关代码写在对应的js中
    hh_chat_window.html

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport -->
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 -->
<meta name="format-detection" content="telephone=no"/>
<title>APP</title>
<link rel="stylesheet" type="text/css" href="../../css/aui.css" />
<!--<link rel="stylesheet" type="text/css" href="../../css/api.css"/>-->
</head>
<style>
.history-date {
font-size: 12px;
}
#message-content {
overflow-y: auto;
}
#wrap {
height: 100%;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-orient: vertical;
-webkit-flex-flow: column;
flex-flow: column;
}
.topbar {
background: #1abc9c;
height: 50px;
/*border-bottom: 1px solid #DDDFE3;*/
line-height: 50px;
text-align: center;
display: none;
color: #ffffff;
font-size: 18px;
}
.activebar {
display: block;
}
.back {
position: absolute;
padding: 1px 10px 0px 10px;
height: 29px;
font-size: 15px;
/*color: #EFEDED;*/
/*z-index: 99999;*/
}
.mTitle {
width: 50%;
font-size: 18px;
text-align: center;
display: inline-block;
word-break: keep-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<body>
<div id="wrap">
<header class="aui-bar aui-bar-nav aui-bar-primary" id="aui-header">
<div id="cloud" class="topbar activebar">
<div id="back" class="back" onclick="back();" tapmode="">
<i class="aui-iconfont aui-icon-left"></i>
</div>
<div class="mTitle" id="mTitle"></div>
<a id=‘menu‘ class="aui-iconfont aui-icon-friends aui-pull-right" style="display:none;"
onclick="showGroupListById();"></a>
</div>
</header>
<div class="aui-content aui-content-padded" id="message-content">
<p class="aui-text-center history-date"></p>
</div>
</div>
<script type="text/javascript" src="../../script/api.js" ></script>
<script type="text/javascript" src="../../script/base_config.js" ></script>
<script type="text/javascript" src="../../script/huihua/hh_chat_window.js"></script>
</body>
</html>

hh_chat_window.js

var header_t;
//顶部header高度
var header_h;
//发送id
var target_id;

var conver_type;
var h_from;
var person_name;
apiready = function() {
//定位header位置,留出上面电池等空隙,苹果需要
var header = $api.byId(‘aui-header‘);
$api.fixStatusBar(header);
header_t = $api.offset($api.byId(‘cloud‘));
header_h = api.pageParam.header_h;
//当前会话用户id和当前会话历史消息从消息列表页点击传递进来
target_id = api.pageParam.targetId;
//真实姓名
person_name = api.pageParam.person_name;

conver_type = api.pageParam.conver_type;

//从哪个页面进入的聊天界面
h_from = api.pageParam.h_from;
initHeaer();

//当前target_id的最大会话id
var old_msg_id = api.pageParam.old_msg_id;
//打开聊天内容frame页面
api.openFrame({
name : ‘hh_chat_frame‘,
scrollToTop : true,
allowEdit : true,
url : ‘../../html/huihua/hh_chat_frame.html‘,
pageParam : {
‘target_id‘ : target_id,
‘old_msg_id‘ : old_msg_id,
‘conver_type‘ : conver_type
},
rect : {
x : 0,
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h - 50,
},
//页面是否弹动 为了下拉刷新使用
bounces : true
});

//安卓关闭
if (api.systemType == ‘android‘) {
backFromChatForAndroid();
}

//加载uichatbox模块
initUichatbox();

};

/**
* 安卓点击返回的时候
* 周枫
* 2015.08.31
*/
function backFromChatForAndroid() {
api.addEventListener({
name : "keyback"
}, function(ret, err) {
back();
});
}

/**
*返回会话列表页面
* 周枫
* 2015.08.08
*/
function back() {
switch(h_from) {
case ‘hh_index‘:
//清楚红点
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘cleanMsg("‘ + target_id + ‘","‘ + conver_type + ‘");‘
});
//重新获取会话列表
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘getCoversationList();‘
});
break;
case ‘txl_index‘:
//清楚红点
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘cleanMsg("‘ + target_id + ‘","‘ + conver_type + ‘");‘
});
//重新获取会话列表
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘getCoversationList();‘
});
api.execScript({
name : ‘index‘,
frameName : ‘txl_index‘,
script : ‘loadData();‘
});
api.execScript({
name : ‘index‘,
frameName : ‘txl_index‘,
script : ‘showMyself();‘
});

break;
case ‘txl_content‘:
//清楚红点
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘cleanMsg("‘ + target_id + ‘","‘ + conver_type + ‘");‘
});
//重新获取会话列表
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘getCoversationList();‘
});

api.execScript({
name : ‘txl_content_window‘,
frameName : ‘txl_content_frame‘,
script : ‘loadData();‘
});
api.execScript({
name : ‘txl_content_window‘,
frameName : ‘txl_content_frame‘,
script : ‘showMyself();‘
});

break;
}

api.closeWin();
}

function reloadTxlIndex() {
// api.alert({
// msg : ‘11111‘
// }, function(ret, err) {
// //coding...
// });
api.execScript({
name : ‘index‘,
frameName : ‘txl_index‘,
script : ‘loadData();‘
});
}

/**
*加载uichatbox模块
* 周枫
* 2015.08.08
*/
function initUichatbox() {
//引入chatbox
var chatBox = api.require(‘UIChatBox‘);
//获取表情存放路径
var sourcePath = BASE_EMOTION_PATH;
//表情存放目录
var emotionData;
//存储表情
getImgsPaths(sourcePath, function(emotion) {
emotionData = emotion;
})
chatBox.open({
placeholder : ‘‘,
//输入框显示的最大行数(高度自适应)
maxRows : 4,
//自定义表情文件夹(表情图片所在的文件夹,须同时包含一个与该文件夹同名的.json配置文件)的路径
//.json文件内的 name 值必须与表情文件夹内表情图片名对应
emotionPath : sourcePath,
//聊天输入框模块可配置的文本
texts : {
//(可选项)JSON对象;录音按钮文字内容
recordBtn : {
//(可选项)字符串类型;按钮常态的标题,默认:‘按住 说话‘
normalTitle : ‘按住 说话‘,
//(可选项)字符串类型;按钮按下时的标题,默认:‘松开 结束‘
activeTitle : ‘松开 结束‘
}
},
//模块各部分的样式集合
styles : {
//(可选项)JSON对象;输入区域(输入框及两侧按钮)整体样式
inputBar : {
borderColor : ‘#d9d9d9‘,
bgColor : ‘#f2f2f2‘
},
//(可选项)JSON对象;输入框样式
inputBox : {
borderColor : ‘#B3B3B3‘,
bgColor : ‘#FFFFFF‘
},
//JSON对象;表情按钮样式
emotionBtn : {
normalImg : BASE_CHATBOX_PATH + ‘/chatBox_face1.png‘
},
//(可选项)JSON对象;附加功能按钮样式,不传则不显示附加功能按钮
extrasBtn : {
normalImg : BASE_CHATBOX_PATH + ‘/chatBox_add1.png‘
},
//JSON对象;键盘按钮样式
keyboardBtn : {
normalImg : BASE_CHATBOX_PATH + ‘/chatBox_key1.png‘
},
//(可选项)JSON对象;输入框左侧按钮样式,不传则不显示左边的语音按钮
speechBtn : {
normalImg : BASE_CHATBOX_PATH + ‘/chatBox_key1.png‘
},
//JSON对象;“按住 录音”按钮的样式
recordBtn : {
//(可选项)字符串类型;按钮常态的背景,支持rgb,rgba,#,图片路径(本地路径,fs://,widget://);默认:‘#c4c4c4‘
normalBg : ‘#c4c4c4‘,
//(可选项)字符串类型;按钮按下时的背景,支持rgb,rgba,#,图片路径(本地路径,fs://,widget://);默认:‘#999999‘;
//normalBg 和 activeBg 必须保持一致,同为颜色值,或同为图片路径
activeBg : ‘#999999‘,
color : ‘#000‘,
size : 14
},
//(可选项)JSON对象;表情和附加功能面板的小圆点指示器样式,若不传则不显示该指示器
indicator : {
//(可选项)字符串类型;配置指示器的显示区域;默认:‘both‘
//取值范围:
//both(表情和附加功能面板皆显示)
//emotionPanel(表情面板显示)
//extrasPanel(附加功能面板显示)
target : ‘both‘,
color : ‘#c4c4c4‘,
activeColor : ‘#9e9e9e‘
}
},
//(可选项)点击附加功能按钮,打开的附加功能面板的按钮样式,配合 extrasBtn 一起使用,若 extrasBtn 参数内 normalImg 属性不传则此参数可不传
extras : {
titleSize : 10,
titleColor : ‘#a3a3a3‘,
//数组类型;附加功能按钮的样式
btns : [{
title : ‘图片‘,
//(可选项)字符串类型;按钮常态的背景图片
normalImg : BASE_CHATBOX_PATH + ‘/chatBox_album1.png‘,
//(可选项)字符串类型;按钮按下时的背景图片
activeImg : BASE_CHATBOX_PATH + ‘/chatBox_album2.png‘
}, {
title : ‘拍照‘,
normalImg : BASE_CHATBOX_PATH + ‘/chatBox_cam1.png‘,
activeImg : BASE_CHATBOX_PATH + ‘/chatBox_cam2.png‘
}]
}
}, function(ret, err) {
//字符串类型;回调的事件类型,
//取值范围:
//show(该模块打开成功)
//send(用户点击发送按钮)
//clickExtras(用户点击附加功能面板内的按钮)
//数字类型;当 eventType 为 clickExtras 时,此参数为用户点击附加功能按钮的索引,否则为 undefined
//字符串类型;当 eventType 为 send 时,此参数返回输入框的内容,否则返回 undefined

//点击附加功能面板
if (ret.eventType == ‘clickExtras‘) {
var c_index = ret.index;
switch(c_index) {
case 0:
// api.confirm({
// title : "提示",
// msg : "您想要从哪里选取图片 ?",
// buttons : ["现在照", "相册选", "取消"]
// }, function(ret, err) {
// //定义图片来源类型
// var sourceType;
// if (1 == ret.buttonIndex) {/* 打开相机*/
// sourceType = "camera";
// } else if (2 == ret.buttonIndex) {
// sourceType = "album";
// } else {
// return;
// }
//相册选
getPicture("album");
// });
break;
case 1:
//现在照
getPicture("camera");
break;
}

}
//点击发送按钮
if (ret.eventType == ‘send‘) {
/*
*1.用户输入文字或表情
*/
/*用户输入表情或文字*/
/*使用读文件方法,读json*/
var sendMsg = transText(ret.msg);
if ($api.trimAll(sendMsg).length != 0) {
//发送消息的函数,后面会有介绍
//发送消息
// chat(sendMsg);
api.execScript({
name : ‘‘,
frameName : ‘hh_chat_frame‘,
script : ‘sendText("‘ + sendMsg + ‘","‘ + conver_type + ‘")‘
});
/*将文字中的表情符号翻译成图片,并可自定义图片尺寸*/
function transText(text, imgWidth, imgHeight) {
var imgWidth = imgWidth || 30;
var imgHeight = imgHeight || 30;
var regx = /\[(.*?)\]/gm;
var textTransed = text.replace(regx, function(match) {
var imgSrc = emotionData[match];
if (!imgSrc) {
//说明不对应任何表情,直接返回
return match;
}
var img = "<img src=" + imgSrc + " width=" + imgWidth + " height=" + imgHeight + ">";
return img;
});
textTransed = transferBr(textTransed);
return textTransed;
}

} else {
//为ipad写的
api.toast({
msg : ‘对不起,消息不能为空‘,
duration : 2000,
location : "middle"
});
}

}
});

//加载录音按钮事件
/**
press(按下录音按钮)
press_cancel(松开录音按钮)
move_out(按下录音按钮后,从按钮移出)
move_out_cancel(按下录音按钮后,从按钮移出并松开按钮)
move_in(move_out 事件后,重新移入按钮区域)
*/
chatBox.addEventListener({
target : ‘recordBtn‘,
name : ‘press‘
}, function(ret, err) {
//开始录音
startRecord();
});
//(松开录音按钮)
chatBox.addEventListener({
target : ‘recordBtn‘,
name : ‘press_cancel‘
}, function(ret, err) {
stopRecord();
});
//move_out(按下录音按钮后,从按钮移出)
chatBox.addEventListener({
target : ‘recordBtn‘,
name : ‘move_out‘
}, function(ret, err) {
api.execScript({
name : ‘‘,
frameName : ‘hh_voice_window‘,
script : ‘moveOut()‘
});
});
//move_out_cancel(按下录音按钮后,从按钮移出并松开按钮)
chatBox.addEventListener({
target : ‘recordBtn‘,
name : ‘move_out_cancel‘
}, function(ret, err) {
api.stopRecord(function(ret, err) {
if (ret) {
removefile(ret.path);
}
});
api.closeFrame({
name : ‘hh_voice_window‘
});
});
//move_in(move_out 事件后,重新移入按钮区域)
chatBox.addEventListener({
target : ‘recordBtn‘,
name : ‘move_in‘
}, function(ret, err) {
api.execScript({
name : ‘‘,
frameName : ‘hh_voice_window‘,
script : ‘moveIn()‘
});
});
//输入框绑定
/**
*
move(输入框所在区域弹动事件)
change(输入框所在区域高度改变)
showRecord(用户点击左侧语音按钮)
showEmotion(用户点击表情按钮)
showExtras(用户点击右侧附加功能按钮,如果 open 时传了 extras 参数才会有此回调)

*/
//move(输入框所在区域弹动事件) 就是输入框收起和弹出变化
chatBox.addEventListener({
target : ‘inputBar‘,
name : ‘move‘
}, function(ret, err) {
// api.toast({msg: JSON.stringify(ret),location: ‘top‘}); //50
// api.toast({msg: JSON.stringify(err),location: ‘middle‘}); //283
//点击输入框时会话界面高度发生变化
setChatFrameByInputMove(ret.inputBarHeight, ret.panelHeight);
});

//change(输入框所在区域高度改变)
chatBox.addEventListener({
target : ‘inputBar‘,
name : ‘change‘
}, function(ret, err) {
// api.toast({msg: JSON.stringify(ret),location: ‘top‘}); //50
// api.toast({msg: JSON.stringify(err),location: ‘middle‘}); //283
//点击输入框时会话界面高度发生变化
setChatFrameByInputChange(ret.inputBarHeight, ret.panelHeight);
});
}

/**
*发送消息
* 周枫
* 2015.08.08
* @param {Object} sendMsg
*/
//function chat(sendMsg) {
// //向会话列表页发送消息事件
// api.sendEvent({
// name : ‘sendMessage‘,
// extra : {
// type : ‘text‘,
// targetId : ‘‘ + target_id + ‘‘,
// content : sendMsg,
// conversationType : ‘PRIVATE‘,
// extra : ‘‘
// }
// })
//}

/**
* 删除文件
* 周枫
* 2015.08.10
* @param {Object} path
*/
function removefile(path) {
var fs = api.require(‘fs‘);
fs.remove({
path : path
}, function(ret, err) {
if (ret.status != true) {
// api.alert({
// msg : err.msg
// }, function(ret, err) {
// //coding...
// });
}
});
}

/**
*开始录音
* 周枫
* 2015.08.10
*/
function startRecord() {
api.openFrame({
name : ‘hh_voice_window‘,
url : ‘../../html/huihua/hh_voice_window.html‘,
scrollToTop : true,
rect : {
x : 0,
y : 0,
w : api.winWidth,
h : api.winHeight - 50,
},
});
//点击后播放开启录音的声音
api.startPlay({
path : ‘widget://res/LowBattery.mp3‘
}, function() {
api.startRecord();
});
}

/**
* 结束录音
* path:‘‘, //字符串,返回的音频地址
duration:0 //数字类型,音频的时长
* 周枫
* 2015.08.10
*/
function stopRecord() {
api.stopRecord(function(ret, err) {
if (ret) {
if (ret.duration == 0) {
api.execScript({
name : ‘‘,
frameName : ‘hh_voice_window‘,
script : ‘moveShort()‘
});
removefile(ret.path);
} else {
api.sendEvent({
name : ‘setVoice‘,
extra : {
voice_result : ret,
conver_type : conver_type
}
});
// api.execScript({
// name : ‘‘,
// frameName : ‘hh_chat_frame‘,
// script : ‘sendVoi("‘ + ret.path + ‘",‘ + ret.duration + ‘)‘
// });
//
// sendVoiceMessage(mytoken, ret.path, ret.duration);
// $api.val($api.byId("record_hid"), ret.path);
}
setTimeout("api.closeFrame({name: ‘hh_voice_window‘})", 400);
}
});
}

/**
* 点击输入框时会话界面高度发生变化
* inputBarHeight: 50, //数字类型;输入框及左右按钮整体区域的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值
panelHeight: 300 //数字类型;输入框下边缘距离屏幕底部的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值
* 周枫
* 2015.08.10
*/
function setChatFrameByInputMove(inputBarHeight, panelHeight) {
if (inputBarHeight > 0) {//输入框打开时
api.setFrameAttr({
name : ‘hh_chat_frame‘,
rect : {
x : 0,
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h - inputBarHeight - panelHeight - 35,
},
});
} else {//关闭时
api.setFrameAttr({
name : ‘chatFrame‘,
rect : {
x : 0,
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h - inputBarHeight - 35,
},
});
}
setTimeout(‘setBottom()‘, 200);
}

/**
* 输入框内文字行数,现设置为最多4行
* inputBarHeight: 50, //数字类型;输入框及左右按钮整体区域的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值
panelHeight: 300 //数字类型;输入框下边缘距离屏幕底部的高度,仅当监听 inputBar 的 move 和 change 事件时本参数有值
* 周枫
* 2015.08.10
*/
function setChatFrameByInputChange(inputBarHeight, panelHeight) {
api.setFrameAttr({
name : ‘hh_chat_frame‘,
rect : {
x : 0,
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h - inputBarHeight - panelHeight - 35,
},
});
setTimeout(‘setBottom()‘, 200);
}

function setBottom() {
api.execScript({
name : ‘‘,
frameName : ‘hh_chat_frame‘,
script : ‘goBottom()‘
});
}

/**
* 通过系统相册或拍照获取图片和视频
sourceType:(可选项)图片源类型,从相册、图片库或相机获取图片, library:图片库,camera:相机,album:相册
encodingType:(可选项)返回图片类型,jpg或png,默认值:png
mediaValue:(可选项)媒体类型,图片或视频 ,pic:图片,video:视频
destinationType:(可选项)返回数据类型,指定返回图片地址或图片经过base64编码后的字符串
allowEdit:(可选项)是否可以选择图片后进行编辑,只支持iOS,默认值:false
quality:(可选项)图片质量,只针对jpg格式图片(0-100整数),默认值:50
targetWidth:(可选项)压缩后的图片宽度,图片会按比例适配此宽度,默认值:原图宽度
targetHeight:(可选项)压缩后的图片高度,图片会按比例适配此高度,默认值:原图高度
saveToPhotoAlbum:(可选项)拍照或录制视频后是否保存到相册,默认值:false
callback
{
data:"", //图片路径
base64Data:"", //base64数据,destinationType为base64时返回
duration:0 //视频时长(数字类型)
}
* 通过系统相册或拍照获取图片和视频
* 周枫
* 2015.08.11
* @param {Object} sourceType
*/
function getPicture(sourceType) {
switch(sourceType) {
case ‘camera‘:
//获取一张图片
api.getPicture({
sourceType : sourceType,
encodingType : ‘png‘,
mediaValue : ‘pic‘,
allowEdit : false,
quality : 80,
// targetWidth : 100,
// targetHeight : 1280,
saveToPhotoAlbum : true
}, function(ret, err) {
if (ret) {
var imgSrc = ret.data;
if (imgSrc != "") {
api.sendEvent({
name : ‘setPicurl‘,
extra : {
imgSrc : imgSrc,
pic_source : ‘camera‘,
conver_type : conver_type
}
});
}
// sendPic(imgSrc);
}
});
break;
case ‘album‘:
//UIMediaScanner 是一个多媒体扫描器,可扫描系统的图片、视频等多媒体资源
var obj = api.require(‘UIMediaScanner‘);
obj.open({
//(可选项)图片显示的列数,须大于1
column : 4,
//(可选项)图片排序方式,asc(旧->新),desc(新->旧)
sort : {
key : ‘time‘,
order : ‘desc‘
},
//(可选项)模块各部分的文字内容
texts : {
stateText : ‘已选择*项‘,
cancelText : ‘取消‘,
finishText : ‘完成‘
},
styles : {
bg : ‘#fff‘,
mark : {
icon : ‘‘,
position : ‘top_right‘,
size : 20
},
nav : {
bg : ‘#eee‘,
stateColor : ‘#000‘,
stateSize : 18,
cancleBg : ‘rgba(0,0,0,0)‘,
cancelColor : ‘#000‘,
cancelSize : 18,
finishBg : ‘rgba(0,0,0,0)‘,
finishColor : ‘#000‘,
finishSize : 18
}
}
}, function(ret) {
//callback
// list: [{ //数组类型;返回选定的资源信息数组
//path: ‘‘, //字符串类型;资源路径,返回资源在本地的绝对路径
//thumbPath: ‘‘, //字符串类型;缩略图路径,返回资源在本地的绝对路径
//suffix: ‘‘, //字符串类型;文件后缀名,如:png,jpg, mp4
//size: 1048576, //数字类型;资源大小,单位(Bytes)
//time: ‘2015-06-29 15:49‘ //字符串类型;资源创建时间,格式:yyyy-MM-dd HH:mm:ss
//}]
if (ret) {
if (getJsonObjLength(ret.list) != 0) {
api.sendEvent({
name : ‘setPicurl‘,
extra : {
image_list : ret.list,
pic_source : ‘album‘,
conver_type : conver_type
}
});
}
}
});
break;
}

}

/**
* 根据群组id获取群组信息页面
* 周枫
* 2015.09.11
*/
function showGroupListById() {
getGroupListById(function(group_list) {
api.openWin({
name : ‘hh_group_window‘,
url : ‘hh_group_window.html‘,
bounces : true,
animation : ‘push‘,
delay : 1,
scrollToTop : true,
pageParam : {
‘targetId‘ : target_id,
‘header_h‘ : header_h,
‘group_list‘ : group_list,
‘group_name‘ : person_name
},
rect : {
x : 0,
y : ‘auto‘,
w : ‘auto‘,
h : ‘auto‘
}
});
});
}

function getGroupListById(callback) {
api.ajax({
url : BASE_URL_ACTION + ‘/dsjxt/getPersonInfoByGroupId?groupId=‘ + target_id + ‘&app_type=‘ + BASE_APP_TYPE,
method : ‘get‘,
dataType : ‘text‘
}, function(ret, err) {
var obj = eval(‘(‘ + ret + ‘)‘);
if (obj) {
callback(obj);
}
});
}

function initHeaer() {
//如果是群组会话,则显示右上角群组成员
if (conver_type == ‘GROUP‘) {
$api.css($api.byId(‘menu‘), ‘display:inline;‘);
}
$api.html($api.byId(‘mTitle‘), person_name);
}

hh_chat_frame.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport -->
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 -->
<meta name="format-detection" content="telephone=no"/>
<title>会话页面frame</title>
<link rel="stylesheet" type="text/css" href="../../css/aui.css" />
<style>
.history-date { font-size: 12px; text-align: center;}
.pic_thumb { max-width:100px;}
</style>
</head>
<body>
<div class="aui-content aui-content-padded" style="padding-top:10px; padding-bottom: 10px;" id="message-content">
<!--<div class="aui-chat-sender history-date"
id="hh_update_div"><p>上拉加载会话记录...</p></div>-->
<!--<div class="aui-chat-sender">
<div class="aui-chat-sender-avatar"><img src="../../image/person/demo_m.png"></div>
<div class="aui-chat-sender-cont">
<div class="aui-chat-right-triangle"></div>
<span>6‘‘<img id="voice_123" alt="98"
src="../../image/chatBox/msendlog.png" width="40px" height="30px"
onclick="playVoice(‘123‘,‘path‘,0);"/></span>
</div>
</div>
<div class="aui-chat-receiver">
<div class="aui-chat-receiver-avatar"><img src="../../image/person/demo_w.png"></div>
<div class="aui-chat-receiver-cont">
<div class="aui-chat-left-triangle"></div>
<span>你好!</span>
</div>
</div>
<div class="aui-chat-sender history-date"><p>7-16 20:00</p></div>
<div class="aui-chat-sender">
<div class="aui-chat-sender-avatar"><img src="../../image/person/demo_m.png"></div>
<div style="float:right; margin: 0 10px 10px 20px; "><em>[图片]</em></div>
<div class="aui-chat-sender-cont">
<div class="aui-chat-right-triangle"></div>-->
<!--<span><img style=" width: 10px; height:
10px; margin-right: 10px; " alt="99"
src="../../image/loading_more.gif"/></span>-->
<!--<span>Hello!!</span>-->
<!--</div>
</div>
<div class="aui-chat-receiver">
<div class="aui-chat-receiver-avatar"><img src="../../image/person/demo_w.png"></div>
<div class="aui-chat-receiver-title"><em>[图片]</em></div>
<div class="aui-chat-receiver-cont">
<div class="aui-chat-left-triangle"></div>
<span>你好!</span>
</div>
</div>-->
</div>
</body>
<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../script/date.js"></script>
<script type="text/javascript" src="../../script/base_config.js"></script>
<script type="text/javascript" src="../../script/huihua/hh_chat_frame.js"></script>
</html>

hh_chat_frame.js

//最后一条消息的 Id,获取此消息之前的 count 条消息,没有消息第一次调用应设置为: -1
var old_msg_id = -1;
//定义发送人
var target_id;

var conver_type;

apiready = function() {
//当前target_id的历史聊天记录
var historyMessages = api.pageParam.historyMessages;
target_id = api.pageParam.target_id;
old_msg_id = api.pageParam.old_msg_id;
conver_type = api.pageParam.conver_type;
//页面加载时获取历史信息
setTimeout(‘initGetHistory("‘ + target_id + ‘", "‘ + old_msg_id + ‘", "‘ + conver_type + ‘", ‘ + 10 + ‘)‘, ‘200‘);
setTimeout(‘goBottom()‘, 500);
//监听收到新消息写入
api.addEventListener({
name : ‘getNewMessage‘
}, function(ret) {
if (ret && ret.value) {
//监听成功
var newMessageData = ret.value;
// api.alert({
// msg : JSON.stringify(newMessageData)
// });
// api.alert({msg:newMessageData.data.objectName });
//根据targetId和当前会话用户id判断一下,如果相等则写入
if (newMessageData.data.targetId == target_id) {
//获取会话列表页数据
var hh_index_list = $api.getStorage(‘hh_index_list‘);
//会话头像
var receive_img;

for (var i = 0; i < hh_index_list.length; i++) {
if ((newMessageData.data.targetId == target_id) &&
(hh_index_list[i].targetId == newMessageData.data.senderUserId)) {
receive_img = hh_index_list[i].avatar_url;
break;
}
if ((newMessageData.data.targetId == target_id) &&
(hh_index_list[i].targetId != newMessageData.data.senderUserId)) {
receive_img = BASE_URL_ACTION + ‘/html/thumb/Material/0D/[email protected]_50h_100Q_1x.jpg‘;
}
}
//如果是群组则显示发送人姓名
if (newMessageData.data.conversationType == "GROUP") {
var group_data = $api.getStorage(‘group_data‘);
var sender_name = group_data[newMessageData.data.senderUserId];
switch(newMessageData.data.objectName) {
case ‘RC:TxtMsg‘:
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-title"><em>‘
+ sender_name + ‘</em></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
newMessageData.data.content.text +
‘</span></div></div>‘);
break;
case ‘RC:ImgMsg‘:
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-title"><em>‘
+ sender_name + ‘</em></div><div
class="aui-chat-receiver-img"><div
class="aui-chat-left-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
newMessageData.data.content.imageUrl + ‘\‘)" src="‘ +
newMessageData.data.content.thumbPath +
‘"></span></div></div>‘);
break;
case ‘RC:VcMsg‘:
// alert(‘11111111111111111‘ + JSON.stringify(newMessageData));
var con = "";
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-title"><em>‘
+ sender_name + ‘</em></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
newMessageData.data.content.duration + ‘\‘\‘<img id="voice_‘ +
newMessageData.data.messageId + ‘" alt="97"
src="../../image/chatBox/mrecelog.png" width="40px" height="30px"
onclick="playVoice(\‘‘ + newMessageData.data.messageId + ‘\‘,\‘‘ +
newMessageData.data.content.voicePath +
‘\‘,1);"/></span></div></div>‘;
// alert(con);
$api.append($api.byId("message-content"), con);
break;
}
} else {
switch(newMessageData.data.objectName) {
case ‘RC:TxtMsg‘:
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
newMessageData.data.content.text +
‘</span></div></div>‘);
break;
case ‘RC:ImgMsg‘:
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-img"><div
class="aui-chat-left-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
newMessageData.data.content.imageUrl + ‘\‘)" src="‘ +
newMessageData.data.content.thumbPath +
‘"></span></div></div>‘);
break;
case ‘RC:VcMsg‘:
// alert(‘11111111111111111‘ + JSON.stringify(newMessageData));
var con = "";
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
newMessageData.data.content.duration + ‘\‘\‘<img id="voice_‘ +
newMessageData.data.messageId + ‘" alt="97"
src="../../image/chatBox/mrecelog.png" width="40px" height="30px"
onclick="playVoice(\‘‘ + newMessageData.data.messageId + ‘\‘,\‘‘ +
newMessageData.data.content.voicePath +
‘\‘,1);"/></span></div></div>‘;
// alert(con);
$api.append($api.byId("message-content"), con);
break;
}
}

}
}
goBottom();
});

//监听发送新消息写入,这个事件主要来处理发送消息插入到会话窗口中
api.addEventListener({
name : ‘insertSendMessage‘
}, function(ret) {
if (ret && ret.value) {
var newMessageData = ret.value;
//我的头像
var sender_img = $api.getStorage(‘avatar_url‘);
// alert(JSON.stringify(newMessageData));
//RC:TxtMsg:文本消息,RC:VcMsg:语音消息,RC:ImgMsg:图片消息,RC:LBSMsg:位置消息
switch (newMessageData.data.message.objectName) {
case ‘RC:TxtMsg‘:
//页面写入发送消息
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-cont"><div
class="aui-chat-right-triangle"></div><span>‘ +
newMessageData.data.message.content.text +
‘</span></div></div>‘);
break;
case ‘RC:ImgMsg‘:
if (api.systemType == ‘ios‘) {
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-img"><div
class="aui-chat-right-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
newMessageData.data.message.content.imageUrl + ‘\‘)" src="‘ +
newMessageData.data.message.content.thumbPath +
‘"></span></div></div>‘);
} else if (api.systemType == ‘android‘) {
$api.append($api.byId("message-content"), ‘<div
class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-img"><div
class="aui-chat-right-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
newMessageData.data.message.content.localPath + ‘\‘)" src="‘ +
newMessageData.data.message.content.thumbPath +
‘"></span></div></div>‘);
}

break;
case ‘RC:VcMsg‘:
var con = "";
con += ‘<div class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-cont"><div
class="aui-chat-right-triangle"></div><span>‘ +
newMessageData.data.message.content.duration + ‘\‘\‘<img id="voice_‘ +
newMessageData.data.message.messageId + ‘" alt="98"
src="../../image/chatBox/msendlog.png" width="40px" height="30px"
onclick="playVoice(\‘‘ + newMessageData.data.message.messageId + ‘\‘,\‘‘
+ newMessageData.data.message.content.voicePath +
‘\‘,0);"/></span></div></div>‘;
$api.append($api.byId("message-content"), con);
break;
}

}
goBottom();
});
//绑定下拉刷新历史会话事件
api.setRefreshHeaderInfo({
visible : true,
loadingImg : ‘widget://image/local_icon_refresh.png‘,
bgColor : ‘#F5F5F5‘,
textColor : ‘#8E8E8E‘,
textDown : ‘下拉加载更多...‘,
textUp : ‘松开加载...‘,
showTime : true
}, function(ret, err) {
//从服务器加载数据,完成后调用api.refreshHeaderLoadDone()方法恢复组件到默认状态
//调用获取历史会话监听
initGetHistory(target_id, old_msg_id, conver_type, 20);
});
//获取历史会话监听,渲染页面
api.addEventListener({
name : ‘setHistory‘
}, function(ret) {
// api.alert({
// msg:‘333:‘+JSON.stringify(ret)
// },function(ret,err){
// //coding...
// });
if (ret && ret.value) {
var historyMessages = ret.value.data;
// api.alert({
// msg:JSON.stringify(historyMessages)
// },function(ret,err){
// //coding...
// });
if (historyMessages != ‘‘) {
var con = ‘‘;
//倒叙循环会话记录
for (var i = getJsonObjLength(historyMessages) - 1; i >= 0; i--) {
var targetid = historyMessages[i].targetId;
var content = ‘‘;
//文字还是图片还是声音 RC:TxtMsg:文本消息,RC:VcMsg:语音消息,RC:ImgMsg:图片消息,RC:LBSMsg:位置消息
var type = historyMessages[i].objectName;
//SEND 还是 RECEVIE
var dir = historyMessages[i].messageDirection;
var start = historyMessages[i].sentTime;
// var end = new Date();
var g_time = new getTimeTemplate();

//我的头像
var sender_img = $api.getStorage(‘avatar_url‘);
//计算会话时间
if (i == historyMessages.length - 1) {
con += ‘<div class="aui-chat-sender history-date"><p>‘ + g_time.getTime(start, 1) + ‘</p></div>‘;
} else {
var M1 = historyMessages[i].sentTime;
var M2 = historyMessages[i + 1].sentTime;
if ((M1 - M2) >= 180 * 1000) {
con += ‘<div class="aui-chat-sender history-date"><p>‘ + g_time.getTime(start, 1) + ‘</p></div>‘;
}
}
//加载会话内容
if (dir == ‘SEND‘) {
switch(type) {
case ‘RC:TxtMsg‘:
con += ‘<div class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-cont"><div
class="aui-chat-right-triangle"></div><span>‘ +
historyMessages[i].content.text +
‘</span></div></div>‘;
break;
case ‘RC:VcMsg‘:
con += ‘<div class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-cont"><div
class="aui-chat-right-triangle"></div><span>‘ +
historyMessages[i].content.duration + ‘\‘\‘<img id="voice_‘ +
historyMessages[i].messageId + ‘" alt="98"
src="../../image/chatBox/msendlog.png" width="40px" height="30px"
onclick="playVoice(\‘‘ + historyMessages[i].messageId + ‘\‘,\‘‘ +
historyMessages[i].content.voicePath +
‘\‘,0);"/></span></div></div>‘;
break;
case ‘RC:ImgMsg‘:
con += ‘<div class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img src="‘ + sender_img +
‘"></div><div class="aui-chat-sender-img"><div
class="aui-chat-right-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
historyMessages[i].content.imageUrl + ‘\‘)" src="‘ +
historyMessages[i].content.thumbPath +
‘"></span></div></div>‘
break;
}

//渲染发送会话
// $api.prepend($api.byId("message-content"), ‘<div
class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img
src="../../image/person/demo2.png"></div><div
class="aui-chat-sender-cont"><div
class="aui-chat-right-triangle"></div><span>‘ +
historyMessages[i].content.text +
‘</span></div></div>‘);
} else {
//获取会话列表页数据
var hh_index_list = $api.getStorage(‘hh_index_list‘);
//会话头像
var receive_img;
for (var j = 0; j < hh_index_list.length; j++) {
if (hh_index_list[j].targetId == historyMessages[i].senderUserId) {
receive_img = hh_index_list[j].avatar_url;
} else {
// receive_img = ‘../../image/person/demo_m.png‘;
receive_img = BASE_URL_ACTION + ‘/html/thumb/Material/0D/[email protected]_50h_100Q_1x.jpg‘;
}
}
if (historyMessages[i].conversationType == "GROUP") {
//获取群组人员姓名
var group_data = $api.getStorage(‘group_data‘);
var sender_name = group_data[historyMessages[i].senderUserId];
switch(type) {
case ‘RC:TxtMsg‘:
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-title"><em>‘
+ sender_name + ‘</em></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
historyMessages[i].content.text +
‘</span></div></div>‘;
break;
case ‘RC:VcMsg‘:
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-title"><em>‘
+ sender_name + ‘</em></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
historyMessages[i].content.duration + ‘\‘\‘<img id="voice_‘ +
historyMessages[i].messageId + ‘" alt="97"
src="../../image/chatBox/mrecelog.png" width="40px" height="30px"
onclick="playVoice(\‘‘ + historyMessages[i].messageId + ‘\‘,\‘‘ +
historyMessages[i].content.voicePath +
‘\‘,1);"/></span></div></div>‘;
break;
case ‘RC:ImgMsg‘:
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-title"><em>‘
+ sender_name + ‘</em></div><div
class="aui-chat-receiver-img"><div
class="aui-chat-left-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
historyMessages[i].content.imageUrl + ‘\‘)" src="‘ +
historyMessages[i].content.thumbPath +
‘"></span></div></div>‘
break;

//渲染接收会话
// $api.prepend($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img
src="../../image/person/demo2.png"></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
historyMessages[i].content.text +
‘</span></div></div>‘);
}
} else {
switch(type) {
case ‘RC:TxtMsg‘:
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
historyMessages[i].content.text +
‘</span></div></div>‘;
break;
case ‘RC:VcMsg‘:
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
historyMessages[i].content.duration + ‘\‘\‘<img id="voice_‘ +
historyMessages[i].messageId + ‘" alt="97"
src="../../image/chatBox/mrecelog.png" width="40px" height="30px"
onclick="playVoice(\‘‘ + historyMessages[i].messageId + ‘\‘,\‘‘ +
historyMessages[i].content.voicePath +
‘\‘,1);"/></span></div></div>‘;
break;
case ‘RC:ImgMsg‘:
con += ‘<div class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img src="‘ + receive_img +
‘"></div><div class="aui-chat-receiver-img"><div
class="aui-chat-left-triangle"></div><span><img
class="pic_thumb" onclick="openImage(\‘‘ +
historyMessages[i].content.imageUrl + ‘\‘)" src="‘ +
historyMessages[i].content.thumbPath +
‘"></span></div></div>‘
break;

//渲染接收会话
// $api.prepend($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img
src="../../image/person/demo2.png"></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
historyMessages[i].content.text +
‘</span></div></div>‘);
}
}

}
//获取刷新后最后一条ID
if (i == historyMessages.length - 1) {
old_msg_id = historyMessages[i].messageId;
}
}
// $api.css($api.byId(‘hh_update_div‘), ‘display:none;‘);
// api.alert({
// msg: con
// },function(ret,err){
// //coding...
// });
//加载历史聊天记录
$api.prepend($api.byId("message-content"), con);
}

}
//通知顶部下拉刷新数据加载完毕,组件会恢复到默认状态
api.refreshHeaderLoadDone();
//隐藏进度提示框
api.hideProgress();
if (old_msg_id == -1) {
goBottom();
}
});

// //监听发送新消息写入,这个事件主要来处理发送消息插入到会话窗口中
// api.addEventListener({
// name : ‘insertSendMessage‘
// }, function(ret) {
// if (ret && ret.value) {
// var newMessageData = ret.value;
// // alert(JSON.stringify(newMessageData));
// //页面写入发送消息
// $api.append($api.byId("message-content"), ‘<div
class="aui-chat-sender"><div
class="aui-chat-sender-avatar"><img
src="../../image/person/demo2.png"></div><div
class="aui-chat-sender-cont"><div
class="aui-chat-right-triangle"></div><span>‘ +
newMessageData.data.message.content.text +
‘</span></div></div>‘);
// }
// });
// //监听收到新消息写入
// api.addEventListener({
// name : ‘getNewMessage‘
// }, function(ret) {
// if (ret && ret.value) {
// //监听成功
// var newMessageData = ret.value;
// //根据targetId和当前会话用户id判断一下,如果相等则写入
// if (newMessageData.data.targetId == targetId) {
// $api.append($api.byId("message-content"), ‘<div
class="aui-chat-receiver"><div
class="aui-chat-receiver-avatar"><img
src="../../image/person/demo2.png"></div><div
class="aui-chat-receiver-cont"><div
class="aui-chat-left-triangle"></div><span>‘ +
newMessageData.data.content.text +
‘</span></div></div>‘);
// }
// }
// });
//绑定发送多个图片的监听
sendPic();
//发送语音消息
sendVoi();
//从后台返回到前台
reAppFromBack();
//下拉刷新数据
// refreshHeaderInfo();
}
/**
*滚动页面底部
* 周枫
* 2015.08.11
*/
function goBottom() {
document.getElementsByTagName(‘body‘)[0].scrollTop = document.getElementsByTagName(‘body‘)[0].scrollHeight;
}

/**
* 发送文本消息
* 周枫
* 2015.08.08
* @param {Object} sendMsg
*/
function sendText(sendMsg, conver_type) {
//向会话列表页发送消息事件
api.sendEvent({
name : ‘sendMessage‘,
extra : {
type : ‘text‘,
targetId : ‘‘ + target_id + ‘‘,
content : sendMsg,
conversationType : conver_type,
extra : ‘‘
}
})
}

/**
* 发送图片消息
* 周枫
* 2015.08.11
* @param {Object} img_url
*/
function sendPic() {
api.addEventListener({
name : ‘setPicurl‘
}, function(ret) {
if (ret && ret.value) {
var value = ret.value;
// alert(JSON.stringify(value));
switch(value.pic_source) {
case ‘camera‘:
//向会话列表页发送消息事件
api.sendEvent({
name : ‘sendMessage‘,
extra : {
type : ‘pic‘,
targetId : ‘‘ + target_id + ‘‘,
imgSrc : value.imgSrc,
conversationType : value.conver_type,
pic_source : value.pic_source,
extra : ‘‘
}
})
break;
case ‘album‘:
//向会话列表页发送消息事件
api.sendEvent({
name : ‘sendMessage‘,
extra : {
type : ‘pic‘,
targetId : ‘‘ + target_id + ‘‘,
img_list : value.image_list,
conversationType : value.conver_type,
pic_source : value.pic_source,
extra : ‘‘
}
})
break;
}

}
});

}

/**
* 发送语音消息
* 周枫
* 2015.08.12
*/
function sendVoi() {
api.addEventListener({
name : ‘setVoice‘
}, function(ret) {
if (ret && ret.value) {
var value = ret.value.voice_result;
// alert(JSON.stringify(value));
//向会话列表页发送消息事件
api.sendEvent({
name : ‘sendMessage‘,
extra : {
type : ‘voi‘,
targetId : ‘‘ + target_id + ‘‘,
voicePath : value.path,
duration : value.duration,
conversationType : ret.value.conver_type,
extra : ‘‘
}
})
}
});
}

/**
* 展示图片
* 周枫
* 2015.08.12
* @param {Object} img_url
*/
function openImage(img_url) {
var img_urls = new Array();
img_urls[0] = img_url;
var obj = api.require(‘imageBrowser‘);
obj.openImages({
imageUrls : img_urls,
//是否以九宫格方式显示图片
showList : false,
activeIndex : 0
});
}

/**
* 播放语音
* 周枫
* 2015.08.12
*/
function playVoice(id, voicePath, whosend) {
var objs = document.getElementsByTagName("img");
for (var i = 0; i < objs.length; i++) {
if (objs[i].alt == ‘98‘) {
objs[i].src = ‘../../image/chatBox/msendlog.png‘;
} else if (objs[i].alt == ‘97‘) {
objs[i].src = ‘../../image/chatBox/mrecelog.png‘;
}
}
api.stopPlay();
if (whosend == 0) {
document.getElementById(‘voice_‘ + id).src = ‘../../image/chatBox/msendgif.gif‘;
} else {
document.getElementById(‘voice_‘ + id).src = ‘../../image/chatBox/mrecegif.gif‘;
}
api.startPlay({
path : voicePath
}, function() {
if (whosend == 0) {
document.getElementById(‘voice_‘ + id).src = ‘../../image/chatBox/msendlog.png‘;
} else {
document.getElementById(‘voice_‘ + id).src = ‘../../image/chatBox/mrecelog.png‘;
}
});
// alert(duration+‘,‘+voicePath);
}

/**
* 获取历史聊天记录
* 周枫
* 2015.08.20
* @param {Object} target_id 会话人
* @param {Object} old_msg_id 最新会话id
* @param {Object} conver_type 会话类型
* @param {Object} msg_count 获取条数
*/
function initGetHistory(target_id, old_msg_id, conver_type, msg_count) {
api.sendEvent({
name : ‘getHistory‘,
extra : {
type : conver_type,
old_msg_id : old_msg_id,
target_id : target_id,
msg_count : msg_count
}
});
}

/**
* 从后台返回
* 周枫
* 2015.09.02
*/
function reAppFromBack() {
api.addEventListener({
name : ‘resume‘
}, function(ret, err) {
goBottom();
});
}

//点击出现气泡按钮功能,暂未实现
//window.addEventListener("touchstart", showBubbleMenu);
//
//function showBubbleMenu(event) {
// var touch = event.touches[0];
// var centerX = touch.clientX;
// var centerY = touch.clientY;
// var bubbleMenu = api.require(‘bubbleMenu‘);
// var btnArray = [{
// "title" : "复制"
// }, {
// "title" : "删除"
// }];
//
// bubbleMenu.open({
// centerX : centerX,
// centerY : centerY,
// btnArray : btnArray,
// fixedOn : api.frameName
// }, function(ret, err) {
// var btn = btnArray[ret.index];
// api.toast({
// msg : ‘您点击了:‘ + btn.title + ‘按钮‘,
// location : ‘top‘
// });
// });
//}

5. 通讯录页面,包括txl_index_window.html和txl_content_window.html两部分,具体如下
txl_index_window.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport -->
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 -->
<meta name="format-detection" content="telephone=no"/>
<title>通讯录列表</title>
<link rel="stylesheet" type="text/css" href="../../css/aui.css" />
<style>
body {
}
</style>
</head>
<body>

<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../script/template.js"></script>
<script type="text/javascript" src="../../script/base_config.js"></script>
<script type="text/javascript" src="../../script/tongxunlu/txl_index_window.js"></script>
</body>
</html>

txl_index_window.js

//顶部header高度
var header_h;

//var listContact;
//定义user_id
var person_id;
//定义身份
var person_identity;
var footer_h;

var old_msg_id = -1;
apiready = function() {
//定位header位置,留出上面电池等空隙,苹果需要
var $header = $api.dom(‘header‘);
$api.fixIos7Bar($header);
header_h = api.pageParam.header_h;
footer_h = api.pageParam.footer_h;
//加载 listContact 模块
listContact = api.require(‘listContact‘);
person_id = $api.getStorage(‘person_id‘);
person_identity = $api.getStorage(‘identity‘);

//监听来自通讯录页面获取最新会话id的事件
api.addEventListener({
name : ‘setOldMessageId‘
}, function(ret) {

if (ret && ret.value) {
var value = ret.value;
old_msg_id = value.old_msg_id;
}
});
};

/**
* 加载通讯录列表
* 周枫
* 2015.08.18
*/
function loadData() {
//根据用户ID获取通讯录数据
getTongXunluByUserId(person_id, person_identity, function(txl_data) {
//打开list
listContact.open({
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h - footer_h,
cellBgColor : ‘#FFFFFF‘,
cellHeight : 60,
indicator : { },
data : txl_data,
borderColor: ‘#DDDFE3‘
}, function(ret, err) {
api.hideProgress();
// index: //点击某个cell所在区域内的cell的下标
// section: //被点击的cell所在的区域的下标
// key: //被点击的cell的区域的key
// clickType: //点击类型,0-cell;1-右边按钮;2-左边的按钮
// btnIndex: //点击按钮时返回其下标
//点击index值
var r_i = ret.index;
// api.alert({
// msg:‘r_i:‘+r_i+‘,key:‘+ret.key+‘,txl_data:‘
// },function(ret,err){
// //coding...
// });
//json串长度
// var l_d = getJsonObjLength(txl_data.common);
//安卓下只有common乱序
// if (ret.key == ‘common‘) {
// if (api.systemType == ‘android‘) {
// //算出正确的值,因为安卓有BUG倒叙
// r_i = l_d - (r_i + 1);
// }
// }

//名字
var title = txl_data[ret.key][r_i].title;
//类型: 1:群组 2:学校 3:班级 4:好友
var t = txl_data[ret.key][r_i].t;
//登录名,target_id
var target_id = txl_data[ret.key][r_i].login_name;

// api.alert({
// msg:
‘target_id:‘+target_id+‘,id:‘+id+‘,title:‘+title+‘,t:‘+t+‘,key:‘+ret.key
+ ",index:" + ret.index+‘,section:‘+ret.section
// });
if (t == 2 || t == 3) {
// hideMyself();
//班级、学校的ID
var id = txl_data[ret.key][r_i].id;
api.openWin({
name : ‘txl_content_window‘,
url : ‘txl_content_window.html‘,
bounces : true,
scrollToTop : true,
animation : ‘push‘,
delay : 1,
pageParam : {
‘header_h‘ : header_h,
‘id‘ : id,
‘title‘ : title,
‘t‘ : t
},
rect : {
x : 0,
y : ‘auto‘,
w : ‘auto‘,
h : ‘auto‘
}
});

} else if (t == 1) {
//初始化群组数据给融云服务器
initGroupInfoByUserId(function(init_group_result) {
if (init_group_result.code == ‘200‘) {
//群组
var id = txl_data[ret.key][r_i].id;
api.openWin({
name : ‘txl_content_window‘,
url : ‘txl_content_window.html‘,
bounces : true,
scrollToTop : true,
animation : ‘push‘,
delay : 1,
pageParam : {
‘header_h‘ : header_h,
‘id‘ : id,
‘title‘ : title,
‘t‘ : t
},
rect : {
x : 0,
y : ‘auto‘,
w : ‘auto‘,
h : ‘auto‘
}
});
}
});
} else if (t == 4) {
//发送target_id获取最新会话id
api.sendEvent({
name : ‘getOldMessageId‘,
extra : {
target_id : target_id,
conver_type : ‘PRIVATE‘,
count : 1
}
});
//打开会话页面
setTimeout(‘execHhList("‘ + target_id + ‘","‘ + title + ‘","PRIVATE");‘, 500);
}
hideMyself();
closeMyself();
});
});

}

/**
* 根据用户ID获取通讯录数据
* 周枫
* 2015.08.21
*/
function getTongXunluByUserId(user_id, user_identity, callback) {
//api.alert({
// msg:user_id+‘,‘+user_identity+‘,‘+BASE_APP_TYPE
//},function(ret,err){
// //coding...
//});
api.ajax({
url : BASE_URL_ACTION + ‘/dsjxt/getAddressBookInfo?user_id=‘ + user_id
+ ‘&user_identity=‘ + user_identity + ‘&app_type=‘ +
BASE_APP_TYPE,
method : ‘get‘,
dataType : ‘text‘
}, function(ret, err) {
var obj = eval(‘(‘ + ret + ‘)‘);
if (obj) {
callback(obj);
}
});
}

/**
* 初始化群组数据给融云服务器
* 周枫
* 2015.09.10
*/
function initGroupInfoByUserId(callback) {
var login_name = $api.getStorage(‘login_name‘);
var person_id = $api.getStorage(‘person_id‘);
var identity = $api.getStorage(‘identity‘);
api.ajax({
url : BASE_URL_ACTION + ‘/rongcloud/initGroupInfoByUserId?login_name=‘
+ login_name + ‘&identity=‘ + identity + ‘&person_id=‘ +
person_id + ‘&ip_addr=‘ + BASE_SERVER_IP + ‘&app_type=‘ +
BASE_APP_TYPE,
method : ‘get‘,
dataType : ‘json‘
}, function(ret, err) {
if (ret.code != ‘200‘) {
api.alert({
msg : "对不起,同步群组信息失败。"
});
} else {
callback(ret);
}
});
}

/**
* 关闭列表
* 周枫
* 2015.08.18
*/
function closeMyself() {
listContact.close();
// api.closeWin();
}

function hideMyself() {
listContact.hide();
}

function showMyself() {
listContact.show();
}

/**
* 延迟打开会话聊天界面
* 周枫
* 2015.08.24
* @param {Object} target_id
* @param {Object} title
* @param {Object} conver_type
* target_id, old_msg_id, person_name, conver_type
*/
function execHhList(target_id, title, conver_type) {
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘openHhList("‘ + target_id + ‘",‘ + old_msg_id + ‘,"‘ + title + ‘","‘ + conver_type + ‘","txl_index");‘
});
}

通讯录内容页面 txl_content_window.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport -->
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 -->
<meta name="format-detection" content="telephone=no"/>
<title>会话列表</title>
<link rel="stylesheet" type="text/css" href="../../css/aui.css" />
<style>
.history-date {
font-size: 12px;
}
#message-content {
overflow-y: auto;
}
#wrap {
height: 100%;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-orient: vertical;
-webkit-flex-flow: column;
flex-flow: column;
}
.topbar {
background: #1abc9c;
height: 50px;
/*border-bottom: 1px solid #DDDFE3;*/
line-height: 50px;
text-align: center;
display: none;
color: #ffffff;
font-size: 18px;
}
.activebar {
display: block;
}
.back {
position: absolute;
padding: 1px 10px 0px 10px;
height: 29px;
font-size: 15px;
/*color: #EFEDED;*/
/*z-index: 99999;*/
}
</style>
</head>
<body>
<div id="wrap">
<header class="aui-bar aui-bar-nav aui-bar-primary" id="aui-header">
<div id="cloud" class="topbar activebar">
<div id="back" class="back" onclick="back()" tapmode="">
<i class="aui-iconfont aui-icon-left"></i>
</div>
<div class="mTitle" id="mTitle"></div>
</div>
</header>
<div class="aui-content aui-content-padded" id="message-content">
<p class="aui-text-center history-date"></p>
</div>
</div>
<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../script/base_config.js"></script>
<script type="text/javascript" src="../../script/tongxunlu/txl_content_window.js"></script>
</body>

</html>

txl_content_window.js

//顶部header高度
var header_h;
var id;
var title;
//类型: 1:群组 2:学校 3:班级 4:好友
var t;
apiready = function() {
//定位header位置,留出上面电池等空隙,苹果需要
var header = $api.byId(‘aui-header‘);
$api.fixStatusBar(header);

header_h = api.pageParam.header_h;
title = api.pageParam.title;
$api.html($api.byId(‘mTitle‘), title);
id = api.pageParam.id;
t = api.pageParam.t;

//安卓关闭
if (api.systemType == ‘android‘) {
backFromChatForAndroid();
}

// api.execScript({
// name:‘index‘,
// frameName : ‘txl_index‘,
// script : ‘closeMyself();‘
// });

//打开通讯录内容frame页面
api.openFrame({
name : ‘txl_content_frame‘,
scrollToTop : true,
url : ‘../../html/tongxunlu/txl_content_frame.html‘,
pageParam : {
‘id‘ : id,
‘t‘ : t,
‘header_h‘ : header_h
},
rect : {
x : 0,
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h,
},
//页面是否弹动 为了下拉刷新使用
bounces : true
});
}
/**
*返回会话列表页面
* 周枫
* 2015.08.08
*/
function back() {
api.execScript({
name : ‘index‘,
frameName : ‘txl_index‘,
script : ‘showMyself();‘
});
api.execScript({
name : ‘index‘,
frameName : ‘txl_index‘,
script : ‘loadData();‘
});

//关闭群组页面
api.execScript({
frameName : ‘txl_content_frame‘,
script : ‘closeMyself();‘
});
api.closeWin();
}

/**
* 安卓点击返回的时候
* 周枫
* 2015.08.31
*/
function backFromChatForAndroid() {
api.addEventListener({
name : "keyback"
}, function(ret, err) {
back();
});
}

txl_content_frame.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport -->
<meta name="viewport"
content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
<!-- 在IOS设备上,有时会将数字转为手机号,这里也要禁止下 -->
<meta name="format-detection" content="telephone=no"/>
<title>会话列表</title>
<link rel="stylesheet" type="text/css" href="../../css/aui.css" />
<style>
body{

}
</style>
</head>
<body>
<div id="txl_data" style="display:none; text-align: center";>暂无数据</div>

<script type="text/javascript" src="../../script/api.js"></script>
<script type="text/javascript" src="../../script/base_config.js"></script>
<script type="text/javascript" src="../../script/tongxunlu/txl_content_frame.js"></script>
</body>

</html>

txl_content_frame.js

//var listContact;
var id;
var header_h;
var user_id, user_identity;
//类型: 1:群组 2:学校 3:班级 4:好友
var t;
var old_msg_id = -1;
apiready = function() {
//加载 listContact 模块
listContact = api.require(‘listContact‘);
id = api.pageParam.id;
t = api.pageParam.t;
user_id = $api.getStorage(‘person_id‘);
user_identity = $api.getStorage(‘identity‘);
header_h = api.pageParam.header_h;
loadData();

//监听来自通讯录页面获取最新会话id的事件
api.addEventListener({
name : ‘setOldMessageId‘
}, function(ret) {

if (ret && ret.value) {
var value = ret.value;
old_msg_id = value.old_msg_id;
}
});
};

/**
* 加载通讯录列表
* 周枫
* 2015.08.18
*/
function loadData() {
getGroupInfo(function(group_list) {
// api.alert({
// msg:JSON.stringify(group_list)
// },function(ret,err){
// //coding...
// });

//根据用户ID获取通讯录数据
// getTongXunluByUserId(person_id, person_identity, function(txl_data) {
//打开list
listContact.open({
y : header_h,
w : api.winWidth,
h : api.winHeight - header_h,
cellBgColor : ‘#FFFFFF‘,
cellHeight : 60,
borderColor: ‘#DDDFE3‘,
indicator : { },
groupTitle:{
size : 12
},
data : group_list
}, function(ret, err) {

//点击index值
var r_i = ret.index;
//聊天类型
var conver_type = group_list[ret.key][r_i].conver_type;
//名字
var title = group_list[ret.key][r_i].title;
var target_id;
//登录名,target_id
switch(conver_type) {
case "PRIVATE":
target_id = group_list[ret.key][r_i].login_name;
break;
case "GROUP":
target_id = group_list[ret.key][r_i].id;
//根据id获取群组内人员信息
getGroupInfoById(target_id);
break;
}
// api.alert({
// msg:target_id
// },function(ret,err){
// //coding...
// });
//发送target_id获取最新会话id
api.sendEvent({
name : ‘getOldMessageId‘,
extra : {
target_id : target_id,
conver_type : conver_type,
count : 1
}
});
//打开会话页面
setTimeout(‘execHhList("‘ + target_id + ‘","‘ + title + ‘","‘ + conver_type + ‘");‘, 500);
});
// });
});

}

/**
* 获取群组信息,包括学校教师,班级学生,群组列表
* 周枫
* 2015.08.25
*/
function getGroupInfo(callback) {
// api.alert({
// msg: ‘t:‘+t+‘,id:‘+id+‘,user_id:‘+user_id+‘,user_identity:‘+user_identity
// },function(ret,err){
// //coding...
// });
api.ajax({
url : BASE_URL_ACTION + ‘/dsjxt/getGroupInfo?t=‘ + t + ‘&id=‘ + id
+ ‘&user_id=‘ + user_id + ‘&user_identity=‘ + user_identity
+‘&app_type=‘ + BASE_APP_TYPE,
method : ‘get‘,
dataType : ‘text‘
}, function(ret, err) {
var obj = eval(‘(‘ + ret + ‘)‘);
if (getJsonObjLength(obj) == 0) {
$api.css($api.byId("txl_data"), "display:block;");
} else {
if (obj) {
callback(obj);
}
}
});
}

/**
* 延迟打开会话聊天界面
* 周枫
* 2015.08.24
* @param {Object} target_id
* @param {Object} title
* @param {Object} conver_type
* target_id, old_msg_id, person_name, conver_type
*/
function execHhList(target_id, title, conver_type) {
closeMyself();
hideMyself();
api.execScript({
name : ‘index‘,
frameName : ‘hh_index‘,
script : ‘openHhList("‘ + target_id + ‘",‘ + old_msg_id + ‘,"‘ + title + ‘","‘ + conver_type + ‘","txl_content");‘
});
}

/**
* 关闭列表
* 周枫
* 2015.08.18
*/
//function closeMyself() {
////api.alert({
////msg:‘123123‘
////},function(ret,err){
//// //coding...
////});
// listContact.close();
// api.closeFrame();
//}

/**
* 关闭列表
* 周枫
* 2015.08.18
*/
function closeMyself() {
listContact.close();
// api.closeWin();
}

function hideMyself() {
listContact.hide();
}

function showMyself() {
listContact.show();
}

我会经常的访问论坛,我也刚使用不久,希望大家能够多给些建议,多交流,我们一起做得更好。

时间: 2024-10-10 04:28:26

apicloud+融云实现即时通讯的相关文章

IOS集成融云SDK即时通讯

相信大家在项目中会用到即时通讯功能,自己去写的话会需要前后台合作,会大大加大开发的周期,所以考虑使用第三方的即时通讯平台,比如现在有融云,环信....等等等!楼主在项目开发过程中使用到过环信和融云,今天就为大家写下IOS端集成环信的方法和可能会遇到的问题.(融云提供聊天会话列表和聊天界面并且允许我们自定义,所以很方便的). 一:准备工作        1.首先打开融云官网http://www.rongcloud.cn/,注册自己的账户,并登陆.        2.点击左边创建应用,在打开的小窗口

Vue+原生App混合开发手记#2 融云即时通讯

最近开发的一个医药项目中要求加入即时通讯,最后选择了融云IM即时通讯服务,融云即时通讯包含Android SDK,iOS SDK以及Web SDK,为了节省开发时间,使用了Web SDK,这样在Android平台和iOS平台上都能表现一致.这是部分界面的效果, 分为两类用户,一类是医生,接受患者的咨询,一类是患者,可以与医生交流: 医生用户看到的界面 患者用户看到的界面 聊天界面       获取App Key 首先进入融云官网,找到Web SDK开发指南,按照提示先注册一个账号,拿到AppKe

融云的Java端实现

产品中要使用融云实现即时通讯,下面是实现步骤: 1 .注册appkey secret,这个是第一步: 2 .下载融云Java客户端 https://github.com/rongcloud/server-sdk-java: 3 .集成到自己项目里. 这个是下载下的,目录很简单 我们把两个包考到自己项目了 ,两个jar放到我们自己的项目lib 里,就可以了. 4.由于我们的业务暂时只需要单聊一对一业务,大概客户端只要实现这几个功能: 1.获取token 2 发消息,我看到融云提供了实时路由,和消息

融云亮相GDG谷歌女性开发者大会 揭秘IMSDK网络优化策略

4 月 20 日,冷雨阻碍不了天津GDG谷歌女性开发者大会的热烈召开,一众开发者.架构师和科技公司创业者云集一堂,就女性开发者的技术.职场.人生多方面话题展开深入探讨.活动由GDG (谷歌开发者社区) 的 Women Tech Leader(WTM)发起并组织,旨在鼓励和促进女性在技术领域的参与.融云作为云通信技术领导者,在大会上就“即时通讯 SDK 的网络优化策略”主题开展演讲,与各界分享多年积累的云通信技术应用经验,同时表达了对全球女性开发者重要地位的支持和鼓励. 作为通信云行业领导企业,融

nodejs向远程服务器发送post请求----融云Web SDK/客户端获取token

最近要用到一个叫融云的及时通讯的SDK,在获取token这个步骤的时候有点卡顿,以防以后碰到类似的问题,再此记录一下. 客户端通过融云 SDK 每次连接服务器时,都需要向服务器提供 Token,以便验证身份,流程如下: 流程如下: 1.客户端获取用户id,并向服务器请求token(注意这里的服务器不是融云的服务器,而是客户端的服务端) 2.客户端的服务端接收到token请求后,向融云的服务器请求token 3.融云服务器接受到token请求,返回token给客户端的服务端. 4.客户端的服务端接

thinkphp整合系列之融云即时通讯在线聊天

随着技术的发展:现代的网站:越来越趋于应用形式了: 不再是像以前那样需要用户刷新页面:获取数据了: 服务器端可以主动向用户推送数据:更加及时性了: 比较突出的就是即时通讯在线聊天: 今个:我们要打造的就是类似于网页版微信的功能: 示例项目:http://git.oschina.net/shuaibai123/thinkphp-bjyadmin 一:注册融云账号 如果我们不是以即时通讯为主营业务:那么建议使用第三方的服务:这里以融云为例: 官网:http://www.rongcloud.cn/ 注

iOS开发融云即时通讯集成详细步骤

1.融云即时通讯iOS SDK下载地址   http://rongcloud.cn/downloads  选择iOS   SDK下载 2.进行应用开发之前,需要先在融云开发者平台创建应用,如果您已经注册了融云开发者帐号,请前往 融云开发者平台 创建应用:如果您还没有注册融云开发者帐号,请前往 融云官方网站 首先注册开发者帐号,注册后创建应用.注册地址  https://developer.rongcloud.cn/signup 3.登陆融云开发者平台 https://developer.rong

融云即时通讯~~

iOS开发融云即时通讯集成详细步骤 端身正义 发表于 2016-04-12 16:12:11 1.融云即时通讯iOS SDK下载地址   http://rongcloud.cn/downloads  选择iOS   SDK下载 2.进行应用开发之前,需要先在融云开发者平台创建应用,如果您已经注册了融云开发者帐号,请前往 融云开发者平台 创建应用:如果您还没有注册融云开发者帐号,请前往 融云官方网站 首先注册开发者帐号,注册后创建应用.注册地址  https://developer.rongclo

Asp.Net WebApi+融云即时通讯+Android构建自己的移动IM

IM,让我敬畏的一项技术 在我的观点里,即时通信,p2p,音视频传输是程序开发中很有难度的领域,这也是为什么我们很少看到有程序员可以在自己的应用里实现这些技术,尤其是即时通信,要实现高稳定性,高并发性,及时性,低流量和弹无虚发,需要丰富的开发经验做支撑,仅仅是拿来一个开源项目恐怕是难以完成这项任务的.放眼看看国内有即时通信技术的,无一不是大公司.大部分的程序开发者的大部分工作时间都是用来做业务层面的开发,根本没有时间和精力去潜心研究一整套的技术框架,因为公司要盈利,要挣钱,没那么多闲钱养着你去专