网易信im对接web端!

概述

最近跟朋友做了一个小程序项目,用到了即时通讯,选择了网易信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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容