美文网首页
网易信im对接web端!

网易信im对接web端!

作者: 磨人的磨磨虫 | 来源:发表于2019-10-11 14:58 被阅读0次

    概述

    最近跟朋友做了一个小程序项目,用到了即时通讯,选择了网易信Im即时通讯,不得不说,网易信的文档写的相当不友好,文档链接:https://dev.yunxin.163.com/docs/product/IM%E5%8D%B3%E6%97%B6%E9%80%9A%E8%AE%AF/%E6%96%B0%E6%89%8B%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97

    谁看谁懵逼。。。

    长话短说,进入正题。

    介绍:这里对接是小程序sdk版本

    第一步
    先去注册网易信账号建立应用,拿到appKey ,appSecret。理解为小程序的appid就OK,应用唯一标识码

    const appKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    const appSecret = "xxxxxxxxxxxx"
    
    export default {
        appKey,
        appSecret
    }
    
    

    第二步
    先把demo拷贝下来,看看代码,这个真的要看看,很有帮助,地址:https://dev.yunxin.163.com/docs/product/IM%E5%8D%B3%E6%97%B6%E9%80%9A%E8%AE%AF/SDK%E5%BC%80%E5%8F%91%E9%9B%86%E6%88%90/Web%E5%BC%80%E5%8F%91%E9%9B%86%E6%88%90/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F

    第三步
    把文档过一遍,不理解跟着我往下看

    第四步
    去控制台打开自己的账号建立几个IM账户,注意这里是纯前端实现,IM用户体系来自网易信数据库,不通过我们自己的服务端后台,记住账户和密码用来测试的
    然后跟我写下面代码试试

    import config from '@/im/config.js'
    let orderCounter=1
    
    class IMController {
        constructor(headers) {
            this.onConnect = this.onConnect.bind(this)
    
            /* 初始化SDk */
            app.globalData.nim = NIM.getInstance({
                // debug: true,
                db: false, // 小程序不支持数据库
                syncSessionUnread: true, // 同步会话的未读数
                autoMarkRead: false, // 不开启自动标记消息已读 此时服务器下推的所有离线消息算未读,漫游消息算已读
                appKey: config.appKey, // 在云信管理后台查看应用的 appKey
                token: headers.token, // 帐号的唯一标识, 用于建立连接
                account: headers.account, // 帐号, 应用内唯一
                onconnect: this.onConnect, // 连接成功
            })
        }
        /** 1 abnormal closure
         * 连接成功
         */
        onConnect() {
            console.log(orderCounter++, '连接成功: ')
            console.log(app.globalData.nim)
        }
    }
    
    const appNim=new IMController({
        token: '测试账号密码',
        account: ‘测试账号’
    })
    
    //下面是一段发送消息的方法
    // 他人account
    let to = this.otherParam.account
    let text='测试消息'
    appNim.sendText({
      scene: 'p2p',
      to,
      text,
      done: (err, msg) => {
        console.log('发送文本消息回调')
        console.log(err)
        console.log(msg)
      }
    })
    

    这样一个Im账号登录连接就成功了,你可以把im类放在全局对象上以便使用,请继续看下代码,它只是一个消息Mock

    // 这里我只介绍几个重点的字段及状态,
    /*
    * @param {string} flow  发送方 (‘out’=>自己)  and (‘in’ =>他人)
    * @param {string} fromNick 目标名称
    * @param {string} scene 聊天类型 ‘p2p’ 点对点
    * @param {string} to 发送者账户
    * @param {string} sessionId 会话id
    * @param {number} time 发送时间
    * 
    */
    export default {
        cc: true,
        flow: "out",
        from: "19b82a32aa30c50fc4c943ff398dfcae",
        fromClientType: "Web",
        fromDeviceId: "f1cbf57270cfe916c270a842085ce75a",
        fromNick: "woshichunlogn",
        idClient: "0376a3107b0d200744be4c87523b7838",
        idServer: "306034218126",
        isHistoryable: true,
        isLocal: false,
        isOfflinable: true,
        isPushable: true,
        isReplyMsg: true,
        isRoamingable: true,
        isSyncable: true,
        isUnreadable: true,
        needMsgReceipt: false,
        needPushNick: true,
        resend: false,
        scene: "p2p",
        sessionId: "p2p-dc46c6ede64c2c7595f0246e8cd146a7",
        status: "success",
        target: "dc46c6ede64c2c7595f0246e8cd146a7",
        text: "fasf",
        time: 1566653977065,
        to: "dc46c6ede64c2c7595f0246e8cd146a7",
        type: "text",
        userUpdateTime: 1566543003373,
    }
    

    看了各项字段应该已经猜到对应的什么了吧,如text消息文案,time发送时间,scene点对点,等等,也可以自己去看看文档。
    这里我要讲重点

    离线消息与漫游消息

    离线消息只能拿到他人的消息列,漫游消息需要在后台管理开启漫游,不然我们是拿不到漫游消息的,漫游消息指的是自己最近发送的消息列,当然会有本地库存储的,但是小程序里是不支持本地数据库的,当然我也是第一次对接,现在我的理解是这样,如有错误请指出。

    会话

    会话指的是你最近跟某个用户产生的一次对话,他是有消息输出的,如QQ会话列表,千万不要把会话跟消息弄混淆了,会话包括消息或多个消息

    第五步
    看到这里,你也大概了解这个流程是怎么建立的,你现在首要的任务是,写好UI界面,然后把我上面登录的方法调通,然后用实例发送一个消息,看看真实的数据,在把官方给的demo模板里的回调方法一个一个抽出来,我把我的例子放出来如下,有些方法和模块搜不到你不用管,因为这个都是逻辑层,自己懂了之后,每个人才会有自己的实现方式,当然我用的uni.app里的vuex....

    import NIM from '@/vendors/NIM_Web_NIM_weixin_v6.7.0.js'
    import NetcallController from './netcall.js'
    import config from '@/im/config.js'
    import store from '@/api/request/store/home.js' // 删除本地缓存
    import common from '@/common/common.js'
    import { hexMD5, utf8 } from '@/utils/md5-utf8'
    
    let app = getApp()
    
    let orderCounter = 1
    export default class IMController {
        constructor(headers) {
            // vuex对象赋给im类
            this.store = headers.$store
    
            this.onConnect = this.onConnect.bind(this)
            this.onSessions = this.onSessions.bind(this)
            this.onMsg = this.onMsg.bind(this)
            this.onRoamingMsgs = this.onRoamingMsgs.bind(this)
            this.onUpdateSession = this.onUpdateSession.bind(this)
            this.onOfflineMsgs = this.onOfflineMsgs.bind(this)
            this.onMyInfo = this.onMyInfo.bind(this)
    
            /* 初始化SDk */
            app.globalData.nim = NIM.getInstance({
                // debug: true,
                db: false, // 小程序不支持数据库
                syncSessionUnread: true, // 同步会话的未读数
                autoMarkRead: false, // 不开启自动标记消息已读 此时服务器下推的所有离线消息算未读,漫游消息算已读
                appKey: config.appKey, // 在云信管理后台查看应用的 appKey
                token: headers.token, // 帐号的唯一标识, 用于建立连接
                account: headers.account, // 帐号, 应用内唯一
                onconnect: this.onConnect, // 连接成功
                onwillreconnect: this.onWillReconnect, // 断开重连
                ondisconnect: this.onDisconnect, // 丢失连接
                onerror: this.onError, // onError
                /* 收到onconnect后,链接已经建立(登录成功), SDK会开始同步数据, 在收到onsyncdone回调后表示SDK完成了数据同步工作, 此时开发者可以进行渲染 UI 等操作了。*/
                onsyncdone: this.onSyncDone,
                // 用户名片
                onmyinfo: this.onMyInfo, // 同步登录用户资料的回调, 会传入用户资料
                // onupdatemyinfo: this.onUpdateMyInfo, // 当前登录用户在其它端修改自己的个人名片之后的回调, 会传入用户资料
                onusers: this.onUsers, //  同步好友用户资料的回调, 会传入用户资料数组 此回调是增量回调, 可以调用nim.mergeUsers来合并数据
                // onupdateuser: this.onUpdateUser, //  用户资料更新后的回调, 会传入用户资料,请参考用户资料更新时机
                // // 机器人列表的回调
                // onrobots: this.onRobots, // 机器人列表事件
                // // 会话
                onsessions: this.onSessions, // 同步最近会话列表回调, 会传入会话列表, 按时间正序排列, 即最近聊过天的放在列表的最后面 此回调是增量回调, 可以调用nim.mergeSessions来合并数据
                onupdatesession: this.onUpdateSession, // 更新会话的回调, 会传入会话对象, 以下情况会收到此回调 收到消息 发送消息 设置当前会话 重置会话未读数
                // // 消息
                onroamingmsgs: this.onRoamingMsgs, // 漫游消息, 对应回调
                onofflinemsgs: this.onOfflineMsgs, // 离线消息, 对应回调 
                onmsg: this.onMsg, // 收到消息
                // // 系统通知
                // onofflinesysmsgs: this.onOfflineSysMsgs, // 同步离线系统通知的回调, 会传入系统通知数组
                // onsysmsg: this.onSysMsg, // 收到系统通知的回调, 会传入系统通知
                // onsysmsgunread: this.onSysMsgUnread, // 收到系统通知未读数的回调
                // onupdatesysmsgunread: this.onUpdateSysMsgUnread, // 更新系统通知未读数的回调
                // onofflinecustomsysmsgs: this.onOfflineCustomSysMsgs, //  同步离线自定义系统通知的回调, 会传入系统通知数组
                // oncustomsysmsg: this.onCustomSysMsg, // 收到自定义系统通知的回调, 会传入系统通知
                // // 收到广播消息
                // onbroadcastmsg: this.onBroadcastMsg,
                // onbroadcastmsgs: this.onBroadcastMsgs,
                // // 事件订阅
                // onpushevents: this.onPushEvents,
            })
            // 发送消息开始登陆
            // store.dispatch({
            //  type: 'Login_StartLogin'
            // })
        }
        /** 1 abnormal closure
         * 连接成功
         */
        onConnect() {
            console.log(orderCounter++, '连接成功: ')
            console.log(app.globalData.nim)
            app.globalData.netcallController = new NetcallController({
                // debug: false,
                debug: true,
                nim: app.globalData.nim,
                store: this.store
            })
        }
        /**
         * 连接出错
         */
        onError(error) {
            console.log('连接出错')
            common.msgHint()
    
            toLogin()
        }
        /**
         * 此时说明 SDK 处于断开状态, 开发者此时应该根据错误码提示相应的错误信息, 并且跳转到登录页面
         */
        onDisconnect(error) {
            console.log('丢失连接');
            if (error) {
                switch (error.code) {
                    // 账号或者密码错误, 请跳转到登录页面并提示错误
                    case 302:
                        common.msgHint({
                            title: 'im的账户或密码错误,需重新登录'
                        })
                        toLogin()
                        break;
                        // 重复登录, 已经在其它端登录了, 请跳转到登录页面并提示错误
                    case 417:
                        common.msgHint({
                            title: '已经在其它端登录了'
                        })
    
                        toLogin()
                        break;
                        // 被踢, 请提示错误后跳转到登录页面
                    case 'kicked':
                        common.msgHint({
                            title: '你被一名用户踢了'
                        })
    
                        toLogin()
                        break;
                    default:
                        break;
                }
            }
        }
        /** 1 abnormal closure
         * 断线重连
         */
        onWillReconnect(obj) {
            // 此时说明 SDK 已经断开连接, 请开发者在界面上提示用户连接已断开, 而且正在重新建立连接
            console.log('断线重连');
            common.msgHint({
                title: '断线重连中,请稍后!',
                duration: 3000
            })
        }
        /** 6
         * 个人名片:存储个人信息到全局数据
         */
        onMyInfo(user) {
            console.log(orderCounter++, ' 个人信息: ')
            console.log(user)
            if (user) {
                this.store.commit('setMyImData', user)
            }
        }
        /** 7
         * 包含名片的好友信息(可能某些字段不全),[{account,avatar,birth,createTime,email,gender,nick,sign,updateTime}]
         */
        onUsers(friends) {
            console.log(orderCounter++, ' 好友信息: ')
            console.log(friends)
        }
        /** 9
         * 同步完成
         */
        onSyncDone() {
            console.log(orderCounter++, '同步完成')
        }
        /**会话
         * [ {id:"p2p-liuxuanlin",lastMsg:{from:'wujie',text:'222',to:"liuxuanlin"}} ]
         */
        onSessions(session) {
            console.log('会话: ')
            console.log(session)
            if (session) {
                // 会话列表
                let chatList = JSON.parse(JSON.stringify(this.store.state.chatList || []))
                // 合并会话列表
                let list = app.globalData.nim.mergeSessions(chatList, session);
            }
        }
        /**
         * 会话更新:收到消息、发送消息、设置当前会话、重置会话未读数 触发
         * {id:'p2p-zys2',lastMsg:{},scene,to,unread,updateTime}
         * {id:'team-1389946935',lastMsg:{attach:{accounts,team},type,users},scene,to,from,type,unread,updateTime}
         */
        onUpdateSession(session) {
            console.log('会话更新: ', session)
            if (session) {
                // 更新会话列表
                app.globalData.netcallController.mergeChatList(session)
            }
        }
        /**
         * 收到消息
         * {cc,flow:"in",from,fromClientType:"Web",fromDeviceId,fromNick,idClient,idServer:"9680840912",isHistoryable:true,isLocal,isMuted, isOfflinable,isPushable,isRoamingable,isSyncable,isUnreadable,needPushNick,resend,scene:"p2p",sessionId:"p2p-zys2",status:"success",target:"zys2",text:"[呕吐]",time,to:"wujie",type:"text",userUpdateTime}
         */
        onMsg(msg) {
            console.log('收到消息', msg.scene, msg.type);
            console.log(msg);
            if (msg) {
                // 更新消息列表
                app.globalData.netcallController.mergeMsg(msg)
            }
        }
        /**
         * 漫游消息:会多次收到,每次只会收到指定人的漫游消息
          // {scene:"p2p",sessionId:"p2p-cs4",timetag:1513153729257,to:"cs4",msg:[{from:'wujie',text:'222',to:'cs4'}]}
          // {scene:"team",sessionId:"team-3944051",timetag:1513153729257,to:"3944051",msg:[{from:'wujie',text:'222',to:'cs4'}]}
         */
        onRoamingMsgs(session) {
            console.log(orderCounter++, ' 漫游消息')
            console.log(session)
    
            if (session) {
                // 合并漫游消息列表
                app.globalData.netcallController.mergeMsgList(session)
            }
        }
        /**
         * 会话离线消息 拿到每条会话的消息列表
         */
        onOfflineMsgs(session) {
            console.log(orderCounter++, ' 会话离线消息')
            console.log(session)
    
            if (session) {
                // 合并离线消息列表
                app.globalData.netcallController.mergeMsgList(session)
            }
        }
    }
    
    
    let toLogin = res => {
        setTimeout(() => {
            // 删除本地缓存
            store.clear()
            uni.reLaunch({
                url: '/pages/login/index'
            })
        }, 1000)
    }
    
    

    我是个懒人,~~喜欢把知识放在脑子里,写了这么多累了,有什么需要咨询的可以私信给我哦,bey

    相关文章

      网友评论

          本文标题:网易信im对接web端!

          本文链接:https://www.haomeiwen.com/subject/xevnectx.html