乐趣区

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

一、简介

本样例是基于即时通讯(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 等讯息的疾速发送与接管。除此之外还实现了好友的增加与删除、黑名单、平安登录、私聊 / 群聊、个人信息设置(二维码 / 头像等)等性能的全方面反对。
代码地址 https://gitee.com/isrc_ohos/i…

五、相干参考链接

样例源码 https://gitee.com/isrc_ohos/i…
OpenHarmony 常识体系工作组 https://gitee.com/openharmony…

退出移动版