IM 即时通讯实战:环信Web IM极速集成

IM 即时通讯实战:环信Web IM极速集成利用环信 IMWeb 端 SDK 快速实现在 Vue js 中发送出一条 HelloWorld webim

大家好,欢迎来到IT知识分享网。

前置技能

  • Node.js 环境已搭建。
  • npm 包管理工具的基本使用。
  • Vue2 或者 Vue3 框架基本掌握或使用。

学习目标

  • 项目中集成 IM 即时通讯实战
  • 利用环信 IM Web SDK 快速实现在 Vue.js 中发送出一条 Hello World!

一、了解环信 IM

  1. 什么是环信 IM?

    环信即时通讯为开发者提供高可靠、低时延、高并发、安全、全球化的通信云服务,支持单聊、群聊、聊天室。提供多平台 SDK 支持,包括:Android、iOS、Web;同时,提供 EaseIM 和 EaseIMKit 以及服务端 REST API,帮助开发者快速构建端到端通信的场景。

  2. 学习完环信 WebIM 之后可以干嘛?

    可以在任意 Web 应用中极速集成搭建即时通讯功能,无论是自己搭建 IM 应用,还是实现产品需求均可以灵活集成进入到自己的项目之中。

二、环信 WebIM 实现通讯的基本流程

前置准备

  1. 有效的开发者 AppKey。 ( 注册环信)(注册参考文档)
  2. 使用 Vue-cli 创建一个空白项目,或已经具备已有待集成项目(此篇文章以 Vue3 为示例,Vue2 同样可以参考此文章)。
  3. 在项目中使用 npm 或者 yarn 安装环信 WebSDK 包,easemob-websdk
  4. 下载环信官方 Vue3-Demo

我们开始

初期配置

在确保已进行 npm install easemob-websdk 安装了环信 SDK 包,并已经下载了 Vue3 官方 Demo,将项目中的 IM 文件拖入自己的项目中。

此文件共两个功能:

  • 引入环信 WebIM-SDK
  • 将引入的 SDK 进行实例化

在这里插入图片描述

DEFAULT_APPKEY修改为自己已注册的 Appkey。

配置监听

<script setup> import { 
    EaseChatClient } from '@/IM/initwebsdk' /* SDK连接 相关监听 */ EaseChatClient.addEventHandler('connection', { 
    onConnected: () => { 
   }, //与环信服务器建联成功回调。 onDisconnected: () => { 
   }, //与环信服务器断开成功回调。 onOnline: () => { 
   }, // 本机网络连接成功。 onOffline: () => { 
   },// 本机网络掉线。 onError: (error) => { 
   }, //SDK Error 回调 }) /* 好友关系相关监听 */ EaseChatClient.addEventHandler('friendListen', { 
    // 收到好友邀请触发此方法。 onContactInvited: (data) => { 
   }, // 联系人被删除时触发此方法。 onContactDeleted: (data) => { 
   }, // 新增联系人会触发此方法。 onContactAdded: (data) => { 
   }, // 好友请求被拒绝时触发此方法。 onContactRefuse: (data) => { 
   }, // 好友请求被同意时触发此方法。 onContactAgreed: (data) => { 
   } }) /* message 相关监听 */ EaseChatClient.addEventHandler('messageListen', { 
    onTextMessage: function (message) { 
   }, // 收到文本消息。 onEmojiMessage: function (message) { 
   }, // 收到表情消息。 onImageMessage: function (message) { 
   }, // 收到图片消息。 onCmdMessage: function (message) { 
   }, // 收到命令消息。 onAudioMessage: function (message) { 
   }, // 收到音频消息。 onLocationMessage: function (message) { 
   }, // 收到位置消息。 onFileMessage: function (message) { 
   }, // 收到文件消息。 onCustomMessage: function (message) { 
   }, // 收到自定义消息。 onVideoMessage: function (message) { 
   }, // 收到视频消息。 onRecallMessage: function (message) { 
   }, // 收到消息撤回回执。 }) </script> 

创建测试 ID

在这里插入图片描述

登录环信

这一步是所有后续操作的第一步

<script setup> import { 
    EaseChatClient } from '@/IM/initwebsdk' const loginValue = reactive({ 
    user: '', //你的测试环信ID password: '' //你的测试环信ID密码 }) //登录接口调用 const loginIM = async () => { 
    try { 
    await EaseChatClient.open({ 
    user: loginValue.username.toLowerCase(), pwd: loginValue.password.toLowerCase() } ); } catch (error) { 
    console.log('>>>>登录失败', error); } } </script> 

紧接着是开始聊天部分。

好友关系

完成这个功能 需要将该项目开启两个页面,一个申请,一个接收,这样才能看到效果 

两种方式:手动关联一个好友,第二种再创建一个测试 ID 之后,调用 SDK 添加好友。

方式一:测试时最简单的方式,手动关联好友

  1. 在管理后台中手动再创建一个 ID
    image.png

2.并手动将新创建的 ID 关联为好友。
在这里插入图片描述

方式二:开发时调用 SDK 接口添加好友

//申请添加好友 const applyAddFriends = () => { 
    EaseChatClient.addContact(targetId, '我想加你为好友!'); }; //接收方登录将会触发 EaseChatClient.addEventHandler('friendListen', { 
    // 收到好友邀请触发此方法。 onContactInvited: (data) => { 
    //同意申请 EaseChatClient.acceptContactInvite(data.from); //拒绝申请 EaseChatClient.declineContactInvite(data.from); }, }); 

进入页面获取好友列表并自行渲染。

<script setup> //获取好友列表 const friendListData = reactive({ 
   }) const { 
    data } = await EaseChatClient.getContacts() data.length > 0 && data.map(item => (friendListData[item] = { 
    hxId: item })) </script> 

收发消息

完成这个功能 需要将该项目开启两个页面,一个发送,一个接收,这样才能看到效果 

发送方发送一条文本消息:

<script setup> const props = defineProps({ 
    nowPickInfo: { 
    type: Object, required: true, default: () => ({ 
   }) } }) const { 
    nowPickInfo } = toRefs(props) const { 
    ALL_MESSAGE_TYPE, CHAT_TYPE } = messageType //发送文本内容 const textContent = ref('') const sendTextMessage = _.debounce(async () => { 
    //如果输入框全部为空格同样拒绝发送 if (textContent.value.match(/^\s*$/)) return const msgOptions = { 
    id: nowPickInfo.value.id, //要发送的目标ID chatType: nowPickInfo.value.chatType, msg: textContent.value, } textContent.value = '' //发送后清空输入框 try { 
    await store.dispatch('sendShowTypeMessage', { 
    msgType: ALL_MESSAGE_TYPE.TEXT, msgOptions }) } catch (error) { 
    console.log('>>>>>>>发送失败+++++++', error) } }, 50) </script> 

接收方接收消息

/* message 相关监听 */ EaseChatClient.addEventHandler('messageListen', { 
    onTextMessage: function (message) { 
    console.log('>>>>收到文本消息'); pushNewMessage(message); //在缓存中Push一条新消息。 }, // 收到文本消息。 }); 

缓存的消息结构示例

messageList:{ 
    //以好友的ID为KEY,如果获取则直接messageList[friendId]取到对应的消息。 friendId:[ { 
    chatType:"singleChat", //聊天类型 单聊或者群聊 ext:{ 
   }, //消息扩展 from:friendId, //消息来源ID id:"", //消息的唯一ID msg:"Hello World!",//消息内容 time:09,//消息发送时间 to:myId,//发送目标ID type:"txt" //消息来源 }, { 
    chatType:"singleChat", ext:{ 
   }, from:friendId, id:"", msg:"Hello World2!", time:09, to:myId, type:"txt" } ], friendId2:[ { 
    chatType:"singleChat", ext:{ 
   }, from:friendId, id:"", msg:"Hello World!", time:09, to:myId, type:"txt" }, ] } 

渲染消息列表

<script setup> import { 
    reactive, ref, computed, toRefs } from 'vue' //获取其id对应的消息内容 const messageData = computed(() => { 
    //如果Message.messageList中不存在的话调用拉取漫游取一下历史消息 return nowPickInfo.value.id && store.state.Message.messageList[nowPickInfo.value.id] || fechHistoryMessage('fistLoad')() }) <template> <div> <div class="messageList_box" v-for="(msgBody, index) in messageData" :key="msgBody.id"> <div v-if="!msgBody.isRecall && msgBody.type !== ALL_MESSAGE_TYPE.INFORM" class="message_box_item" :style="{ flexDirection: (isMyself(msgBody) ? 'row-reverse' : 'row') }"> <div class="message_item_time">{ 
   { 
    handleMsgTimeShow(msgBody.time, index) || '' }}</div> <el-avatar class="message_item_avator" :src="isMyself(msgBody) ? loginUserInfo.avatarurl : otherUserInfo(msgBody.from).avatarurl || defaultAvatar"> </el-avatar> <el-dropdown class="message_box_content" :class="[isMyself(msgBody) ? 'message_box_content_mine' : 'message_box_content_other']" trigger="contextmenu" placement="bottom-end"> <!-- 文本类型消息 --> <p style="padding: 10px" v-if="msgBody.type === ALL_MESSAGE_TYPE.TEXT"> { 
   { 
    msgBody.msg }} </p> <!-- 图片类型消息 --> <!-- <div> --> <el-image v-if="msgBody.type === ALL_MESSAGE_TYPE.IMAGE" style="border-radius:5px;" :src="msgBody.thumb" :preview-src-list="[msgBody.url]" :initial-index="1" fit="cover" /> <!-- </div> --> <!-- 语音类型消息 --> <div :class="['message_box_content_audio', isMyself(msgBody) ? 'message_box_content_audio_mine' : 'message_box_content_audio_other']" v-if="msgBody.type === ALL_MESSAGE_TYPE.AUDIO" @click="startplayAudio(msgBody, index)" :style="`width:${msgBody.length * 10}px`"> <span class="audio_length_text"> { 
   { 
    msgBody.length }}′′ </span> <div :class="[isMyself(msgBody) ? 'play_audio_icon_mine' : 'play_audio_icon_other', audioPlayStatus.playIndex === index && 'start_play_audio']" style=" background-size: 100% 100%;"> </div> </div> <div v-if="msgBody.type === ALL_MESSAGE_TYPE.LOCAL"> <p style="padding: 10px">[暂不支持位置消息展示]</p> </div> <!-- 文件类型消息 --> <div v-if="msgBody.type === ALL_MESSAGE_TYPE.FILE" class="message_box_content_file"> <div class="file_text_box"> <div class="file_name">{ 
   { 
    msgBody.filename }}</div> <div class="file_size">{ 
   { 
    fileSizeFormat(msgBody.file_length) }}</div> <a class="file_download" :href="msgBody.url" download>点击下载</a> </div> <span class="iconfont icon-wenjian"></span> </div> <!-- 自定义类型消息 --> <div v-if="msgBody.type === ALL_MESSAGE_TYPE.CUSTOM" class="message_box_content_custom"> <template v-if="msgBody.customEvent && CUSTOM_TYPE[msgBody.customEvent]"> <div class="user_card"> <div class="user_card_main"> <!-- 头像 --> <el-avatar shape="circle" :size="50" :src="msgBody.customExts && msgBody.customExts.avatarurl || msgBody.customExts.avatar || defaultAvatar" fit="cover" /> <!-- 昵称 --> <span class="nickname">{ 
   { 
    msgBody.customExts && msgBody.customExts.nickname || msgBody.customExts.uid }}</span> </div> <el-divider style="margin:5px 0; border-top:1px solid black;" /> <p style="font-size: 8px;">个人名片</p> </div> </template> </div> <template #dropdown> <el-dropdown-menu> <el-dropdown-item v-if="msgBody.type === ALL_MESSAGE_TYPE.TEXT && isSupported" @click="copyTextMessages(msgBody.msg)"> 复制 </el-dropdown-item> <el-dropdown-item v-if="isMyself(msgBody)" @click="recallMessage(msgBody)"> 撤回 </el-dropdown-item> <el-dropdown-item @click="deleteMessage(msgBody)"> 删除 </el-dropdown-item> <el-dropdown-item v-if="!isMyself(msgBody)" @click="informOnMessage(msgBody)"> 举报 </el-dropdown-item> </el-dropdown-menu> </template> </el-dropdown> </div> <div v-if="msgBody.isRecall" class="recall_style">{ 
   { 
    isMyself(msgBody) ? "你" : `${ 
     msgBody.from}` }}撤回了一条消息<span class="reEdit" v-show="isMyself(msgBody) && msgBody.type === ALL_MESSAGE_TYPE.TEXT" @click="reEdit(msgBody.msg)">重新编辑</span></div> <div v-if="msgBody.type === ALL_MESSAGE_TYPE.INFORM" class="inform_style"> <p> { 
   { 
    msgBody.msg }} </p> </div> </div> <ReportMessage ref="reportMessage" /> </div> </template> </script> 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/112845.html

(0)
上一篇 2024-11-17 13:00
下一篇 2024-11-17 13:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信