ITPub博客

首页 > 应用开发 > IT综合 > 玩转OpenHarmony社交场景:即时通讯平台

玩转OpenHarmony社交场景:即时通讯平台

IT综合 作者:HarmonyOS开发者社区 时间:2023-01-03 16:09:45 0 删除 编辑

一、简介

本样例是基于即时通讯(Instant messaging,简称IM)服务实现的OpenAtom OpenHarmony(简称“OpenHarmony”)应用,允许两人或多人使用互联网即时地传递文字、图片、文件、语音、emoji等讯息,可应用于各类聊天场景,为人们带来更加及时高效的通讯体验。

此外即时通讯平台具备较高的定制化特点,适用于多种行业,客户可以根据自己的需求来定制,实现即时通讯的内部私有化。

设备端:DAYU200(RK3568)开发板,OpenHarmony 3.1 release系统。

二、即时通讯实现原理

想要实现多个设备之间的无障碍即时通讯,需要多台终端设备、终端应用和服务器配合一起使用。首先应该将终端应用安装到终端设备上,用户通过应用向服务器申请注册账号。随后,用户可以通过账号进行查找,添加其他好友,并向好友发送文字、图片、文件、语音、emoji等讯息。用户发送的讯息会先送达服务器,由服务器判断其好友的状态(离线/在线),然后选择发送或者暂时缓存消息等操作。最后,好友的终端应用接收到消息。

实现即时通讯的设备需求 :安装应用的终端设备、网络环境和云端服务器。

前提条件 :用户将应用安装在终端设备上,并且拥有注册账号,且需要通讯的用户也成功注册了账号并且添加了好友。

通讯原理 :用户在安装了应用的终端设备上编辑信息(文字、图片、文件、语音、emoji等),通过网络将消息发送至云端服务器。当对方用户在线时,云端服务器将把消息推送给对方用户,对方用户安装了应用的终端设备也将接收到信息。当对方用户不在线时,信息将被暂时缓存在云端服务器。

三、4步实现多人即时通讯

(1) 通讯功能通讯功能是通过TCP协议实现的,我们将通讯接口connect()、send()、receive()的实现放置在CPP文件中,通过NAPI的方式对JS层暴露接口。

• connect():客户端和服务器建立连接;

• send():消息发送功能

• receive():消息接收功能;


//

建立

TCP

连接


if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
    napi_create_int32(env, 0, &result);
} else {
    napi_create_int32(env, 1, &result);
    OH_LOG_INFO(LOG_APP,"C++ 接收线程启动 ");
    startRec();
}
 // 发送消息
if(send(sock_cli, data, strlen(data),0) == -1) {
    OH_LOG_INFO(LOG_APP,"zjf == send() : -1");
    napi_create_int32(env, 0, &result);
} else {
    OH_LOG_INFO(LOG_APP,"zjf == send() : !-1");
    napi_create_int32(env, 1, &result);
}
// 接收消息
getStep(queue0,sharedMessage); // 取出一条消息
const char *c_s=sharedMessage.c_str();// 换为 char* 形式处理
napi_value result;
napi_create_string_utf8(env, c_s, sharedMessage.length(), &result);
std::string().swap(sharedMessage);// 清空字符串

(2) 文件消息的发送与接收

文件转发是即时通讯办公场景下的重要功能。样例中的文件功能支持文件消息的发送、接收和下载。用户通过点击聊天界面的“+”按钮,选择“文件”按钮,完成本地文件的浏览,随后可以选择是否将文件发送给好友。这个功能的实现包括三个步骤:(1)文件的选择;(2)文件上传到服务器;(3)文件的接收。

• 文件上传


//

文件的选择


let file1 = {filename: this.$app.$def.uid +'-'+ FILE_URL, name: 'file', uri: FILE_URL, type:fileType }
let fileId = this.guid();
let data = {};
let header = { "filename": this.selectedFileName.toString()};
// 文件上传到服务器
request.upload({ url: "http://" + this.$app.$def.ip +"/file/fileUpload?fileSignature=" + fileId + "&uid=" +this.$app.$def.uid + "&fileType=" +this.$app.$def.chatData[this.idx].unRead, header: header, method: "POST", files: [file1], data: [data] }).then((data) => {
  uploadTask = data;
  uploadTask.on('headerReceive', function callback(headers){
  _this.socketSendFile(fileId, timestamp);
  });
}).catch((err) => {
  console.error('fileSelect=====Failed to request the upload. Cause: ' + JSON.stringify(err));
})
// 文件的接收
let downloadConfig = {  // 下载参数
            url: fileUrl,
            header: {},
            enableMetered: true,
            enableRoaming: true,
            filePath: '/data/storage/el2/base/haps/entry/files/' + downloadFileName,
            networkType: request.NETWORK_WIFI
}
request.download(downloadConfig, (err, data) => {
        if (err) {
            return;
        }
        downloadTask = data;
        // 下载完成
        downloadTask.on('complete', function callback() {
                prompt.showToast({
                   message: ' 下载文件成功! ',
                   duration: 1000,
                });
        });

(3) 语音消息的发送与接收

用户通过点击聊天界面的录制按钮,完成语音的录制,随后可以选择是否将语音发送给好友。这个功能的实现包括三个步骤:(1)语音的录制;(2)语音上传到服务器;(3)语音的接收。

图片消息的发送与语音消息的发送步骤相同,文章中不再赘述。


//

语音录制


startRecorder ( config , callback ) {
     if ( typeof ( this . audioRecorder ) !== 'undefined' ) {
         this . audioRecorder . on ( 'prepare' , () => {
         this . audioRecorder . start ()
     })
         this . audioRecorder . on ( 'start' , () => {
             callback ()
         })
         this . audioRecorder . prepare ( config )
      } else {
        logger . info ( `${TAG} case failed, audiorecorder is null` )
     }
}

// 录制好的语音文件的位置
let srcPath = 'internal://cache/' + this . mainData . file + '.wav'
let file1 = { filename : this . $app . $def . uid + '-' + this . mainData . path , name : 'audio' , uri : srcPath , type : "wav" };

// 语音消息发送到服务器
request . upload ({ url : myurl , header : header , method : "POST" , files : [ file1 ], data : [ data ] }). then (( data ) => {
            uploadTask = data ;
            uploadTask . on ( 'headerReceive' , function callback ( headers ){
              _this . sendAudio ( audioId )
             });
            uploadTask . on ( 'progress' , function callback ( uploadedSize , totalSize ) {
                 console . info ( "dialogPages=====upload totalSize:" + totalSize + "  uploadedSize:" + uploadedSize );
             });
         }). catch (( err ) => {
             console . error ( 'dialogPages=====Failed to request the upload. Cause: ' + JSON . stringify ( err ));
         })
// 语音的接收
let downloadConfig = {      // 下载参数
        url : item . content . path ,
        header : {},  
        enableMetered : true ,                       
        enableRoaming : true ,                       
        filePath : filePath ,                
        networkType : request . NETWORK_WIFI         
}
         let downloadTask ;
         let _this = this
        request . download ( downloadConfig , ( err , data ) => {
             if ( err ) {
                  return ;
             }
            downloadTask = data ;
             // 下载完成
            downloadTask . on ( 'complete' , function callback () {
                let audio = {
                  content : { path : filePath }
                  }
                 _this . playAudio ( audio )
             });

(4) emoji消息的发送与接收

emoji 是即时通讯软件不可缺少的一部分,可以更加生动地表现用户的聊天情感。在样例中,用户通过点击聊天界面的emoji按钮,即可找到目前应用内支持的所有样式的emoji,随后可以选择具体样式并将其发送给好友。


//

引入

emoji

第三方组件


< element name = "emojiExpression" src = "../../common/components/emojiExpression/emojiExpression.hml" ></ element >

// 第三方组件的展示布局
< div id = "moreContainer" if = "{{showFace}}" >
     < div id = "moreOneLine" >
         < div class = "moreFillGap" style = "flex: 1 1;" ></ div >
         < text style = "left: 25fp; top: 10fp;" > 所有表情 </ text >
         < emojiExpression ></ emojiExpression >
         < div class = "moreFillGap" style = "flex: 1 1;" ></ div >
     </ div >
</ div >

四、即时通讯功能总结

本样例是基于OpenHarmony实现的即时通讯应用,目前已经支持文字、图片、文件、语音、emoji等讯息的快速发送与接收。除此之外还实现了好友的添加与删除、黑名单、安全登录、私聊/群聊、个人信息设置(二维码/头像等)等功能的全方面支持。

代码地址

五、相关参考链接

样例源码

OpenHarmony 知识体系工作组

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047792/viewspace-2930596/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2021-11-18

  • 博文量
    401
  • 访问量
    296723