網(wǎng)易云信IM(H5移動端SDK)使用

QQ截圖20181229085012.png

最近體驗(yàn)了下云信SDK
直接上干貨蒲稳,不廢話剩胁!

下載地址:
SDK:https://netease.im/im-sdk-demo
Demo:https://github.com/netease-im/NIM_Web_Demo_H5
入手指南:https://dwz.cn/Hq6Biq2O
服務(wù)端Api:https://dwz.cn/F3Xpc1aR
私聊上傳:http://nos.netease.com/vod163/upload.js
表情:http://www.jq22.com/jquery-info16078

本篇內(nèi)容為:云信Sdk+jquery.emoticons實(shí)現(xiàn)聊天功能
應(yīng)用在web移動端,用戶間會話溝通和客服等功能祥国。
PS:本篇提供基礎(chǔ)實(shí)現(xiàn)方法昵观,不提供界面ui,用哪個表情插件都可以舌稀,比如大笑的表情對應(yīng)[大笑]啊犬,轉(zhuǎn)義后從json找到對應(yīng)url。

一.獲取自己的appKey壁查,具體方法云信官方有觉至。

注冊云信帳號——>登錄網(wǎng)易云信管理后臺——>創(chuàng)建應(yīng)用——>獲取appkey

二.引入SDK,demo分離太麻煩睡腿,此處并未使用

<script type="text/javascript" src="/js/im/NIM_Web_SDK_v5.9.1.js"></script>
需要注意的是:在本機(jī)靜態(tài)頁面測試時容易報錯语御,需要發(fā)布項(xiàng)目,使用127.0.0.1:XX或者localhost等都可以過關(guān);在使用fis3等優(yōu)化時席怪,如果進(jìn)入頁面sdk報錯应闯,將sdk單獨(dú)處理不要fis等。

三.初始化參數(shù)

會話列表頁常用:

var nim = SDK.NIM.getInstance({
    // 初始化SDK
    appKey: 'xxx',
    account: 'xxx',
    token: 'xxx',
    customTag: 'tag',
    onconnect: onConnect,
    onerror: onError,
    onwillreconnect: onWillReconnect,
    ondisconnect: onDisconnect,
    // 多端
    onloginportschange: onLoginPortsChange,
    // 會話
    onsessions: onSessions,
    onupdatesession: onUpdateSession,
    // 同步完成
    onsyncdone: onSyncDone
});

//此處隱藏onConnect挂捻,onError等方法
//請復(fù)制官方初始化代碼碉纺,然后修改加入以下

function onSessions(sessions) {
    console.log('收到會話列表', sessions);
    data.sessions = nim.mergeSessions(data.sessions, sessions);
    updateSessionsUI(sessions);
}

function onUpdateSession(session) {
    console.log('會話更新了', session);
    data.sessions = nim.mergeSessions(data.sessions, session);
    //對html進(jìn)行局部更新,和grid操作類似
    updatePartUI(session);
}

四.會話列表展現(xiàn)

function updateSessionsUI(sessions){
    //這里取當(dāng)天時間细层,后面會用在列表會話時間上惜辑,例如:12-20(今日之前)和9:35(當(dāng)日)
    var today = new Date(new Date().setHours(0, 0, 0, 0)) / 1;
    //...你的時間處理,可使用下方的timestampToTime()
    //你的頁面更新操作
    var html = ""
    for (var i = 0 ; i < sessions.length; i++) {
        //...
        html+="...";
    }
    $('#').append(html);
}

function updatePartUI(session){
    //根據(jù)列表html結(jié)構(gòu)更新和排序
}

//時間戳處理
function timestampToTime(timestamp) {
    var times = new Date(parseInt(timestamp));
    var t = times.toLocaleDateString().replace(/\//g, "-").substr(5,9)+ " " + times.toTimeString().substr(0,5);     
    return t;
}

//私聊
$(document).on("click",'#nim_container table',function(){
    //需要提供account和token來進(jìn)行雙方會話
    //在sessions會話列表里都是有的
    var im_account ="";
    var im_token = "";
    var url="../index?account_id="+im_account+"&token_id="+im_token;
    window.location.href=url; 
});

五.私聊、表情疫赎、圖片上傳的實(shí)現(xiàn)

//加載云信SDK
//獲取會話對象
var nimParam = getUrlParam();
var data = {};
var nim = SDK.NIM.getInstance({
    // 初始化SDK
    appKey: 'xxxxxx',
    account: nimParam.account_id,
    token: nimParam.token_id,
    customTag: 'tag',
    onconnect: onConnect,
    onerror: onError,
    onwillreconnect: onWillReconnect,
    ondisconnect: onDisconnect,
    // 多端
    onloginportschange: onLoginPortsChange,
    // 消息
    onmsg: onMsg,
    // 同步完成
    onsyncdone: onSyncDone
});

//...沒什么用的我就不寫了盛撑,自己加自己要的

function onMsg(msg) {
    console.log('收到消息', msg.scene, msg.type, msg);
    pushMsg(msg);
}

//同步完成后獲取歷史信息
function onSyncDone() {
    nim.getHistoryMsgs({
      scene: 'p2p',
      to: nimParam.nim_fromId,
      done: getHistoryMsgsDone
  });
}

function getHistoryMsgsDone(error, obj) {
    if (!error) {
        console.log(obj.msgs);
        pushMsg(obj.msgs);
    }
}

//輸出聊天信息,表情轉(zhuǎn)義
function pushMsg(msgs) {
    if (!Array.isArray(msgs)) { msgs = [msgs]; }
    if (msgs[0]!=null) {
        var sessionId = msgs[0].sessionId;
        data.msgs = data.msgs || {};
        data.msgs[sessionId] = nim.mergeMsgs(data.msgs[sessionId], msgs);
        var emoticonPath = '/img/im/';
        var msgHtml , title , emoticonUrl , shwoType ,msgsText;
        var filter = /[\[\]]/g;
        for (var i = msgs.length - 1; i >= 0; i--) {
            //輸出內(nèi)容
            if (msgs[i].type=="text"){
                msgsText = msgs[i].text;
                //表情字符轉(zhuǎn)義
                var msgsList = msgsText.match(/\[[\u4e00-\u9fa5]*\w*\]/g);
                if(msgsList){
                   for(var e=0;e<msgsList.length;e++){
                        title = msgsList[e].replace(filter,'');
                        //獲取表情路徑
                        for (var p = 0; p < emoticonsList.length; p++) {
                            if (emoticonsList[p].title==title) {
                                emoticonUrl = emoticonsList[p].url;
                                break;
                            }
                        }
                        //錯誤格式默認(rèn)表情笑容
                        if (emoticonUrl == undefined) {
                            emoticonUrl = emoticonsList[0].url;
                        }
                        msgsText = msgsText.replace(msgsList[e],'<img src="'+emoticonPath+"emoticons/"+emoticonUrl+'"/> ');
                    }    
                }
            }else if (msgs[i].type=="image"){
                msgsText = '<img src="'+msgs[i].file.url+'"/>';
            }

            //以下是你的html結(jié)構(gòu)
            //你的對話框樣式
            if (msgs[i].flow=="out") {
                shwoType = "";  
            }else{
                //..
            }
            msgHtml="<div class='"+shwoType+"'><div class='msg'><div class='portrait'>"
                +"<img src='"+emoticonPath+"touxiang.png' alt=''/></div>"
                +"<div class='msg_content'>"+msgsText+"</div></div></div>";
            upView(msgHtml);
        }
        anchor();
    }
}

//發(fā)送信息成功后更新
function sendMsgDone(error, msg) {
    console.log('發(fā)送' + msg.scene + ' ' + msg.type + '消息' + (!error?'成功':'失敗') + ', id=' + msg.idClient);
    pushMsg(msg);
}

//回車和發(fā)送按鈕操作
$('#dialogue').bind('keypress', function (event) { 
    if (event.keyCode == "13") { 
        sendMsgs();
    }
});

$('.im_send').click(function(){
    sendMsgs();
});

//發(fā)送文本信息
function sendMsgs(){
    var dialogue = document.getElementById("dialogue");
    if($.trim(dialogue.value).length != 0){
        var msg = nim.sendText({
            scene: 'p2p',
            to: nimParam.nim_fromId,
            text: dialogue.value,
            done: sendMsgDone
        });
        dialogue.value = "";
    }
}

//發(fā)送圖片,具體參數(shù)請查看官方API
//此處需要upload.js捧搞、md5.js(頁首有下載鏈接)
function sendFile(curFile){
    nim.sendFile({
        scene: 'p2p',
        to: nimParam.nim_fromId,
        type: 'image',
        fileInput: curFile,
        fastPass: '{"w":200,"h":110,"md5":"xxxxxxxxx"}',
        beginupload: function(upload) {
            // - 如果開發(fā)者傳入 fileInput, 在此回調(diào)之前不能修改 fileInput
            // - 在此回調(diào)之后可以取消圖片上傳, 此回調(diào)會接收一個參數(shù) `upload`, 調(diào)用 `upload.abort();` 來取消文件上傳
        },
        uploadprogress: function(obj) {
            // console.log('文件總大小: ' + obj.total + 'bytes');
            // console.log('已經(jīng)上傳的大小: ' + obj.loaded + 'bytes');
            // console.log('上傳進(jìn)度: ' + obj.percentage);
            // console.log('上傳進(jìn)度文本: ' + obj.percentageText);
        },
        uploaddone: function(error, file) {
            // console.log(error);
            // console.log(file);
            console.log('上傳' + (!error?'成功':'失敗'));
        },
        beforesend: function(msg) {
            // console.log('正在發(fā)送p2p image消息, id=' + msg.idClient);
        },
        done: sendMsgDone
    });
}

/*更新視圖*/
function upView(html){
    $('#js-nim_msg').append(html);
}

//頁末錨點(diǎn)
function anchor(){
    $('body,html').animate({scrollTop: $('.msg_content:last').offset().top});
}

//獲取nim_url參數(shù)
function getUrlParam(name) {
    var search=location.search;
    var params={}; 
    if(search!=""){
        search.slice(1).split("&").forEach(function(val){
            var arr=val.split("=");
            params[arr[0]]=arr[1]; 
        });
    }
    return params;   //返回params
}

//表情頁展現(xiàn)
$('.nim_expression').click(function(){
    resetmode();
    if($('#js-nim_emoticon').is(':hidden')){
        $('#js-nim_emoticon').show(200);
        $('#js-nim_footer').css('bottom','2.2rem');
        $('#nim_anchor').height('2.2rem');
    }
    anchor();
});

//添加文件
$('#nim_more').click(function(){
    //fileInput為type='file'的文本框抵卫,點(diǎn)擊按鈕圖片時單擊文本框,上傳的文件必須儲存在file內(nèi)胎撇。
    $("#fileInput").click();
});

//重置表情介粘、更多內(nèi)容等都寫在這個位置
function resetmode(){
    $('#js-nim_more').hide(200);
    $('#js-nim_emoticon').hide(200);
    $('#nim_anchor').height(0);
    $('#js-nim_footer').css('bottom','0rem');
}

//載入表情
$.emoticons({
    'activeCls':'trigger-active'
});

//選擇表情后轉(zhuǎn)義添加到文本
$('#im_emoticons img').click(function(){
    var format = "["+$(this).attr("title")+"]";
    var dialogue = document.getElementById("dialogue");
    dialogue.value = dialogue.value + format;
});


/**
 *  加載表情,位置自己放
 */
;(function (factory) {
    if (typeof define === "function" && (define.amd || define.cmd) && !jQuery) {
        // AMD或CMD
        define([ "jquery" ],factory);
    } else if (typeof module === 'object' && module.exports) {
        // Node/CommonJS
        module.exports = function( root, jQuery ) {
            if ( jQuery === undefined ) {
                if ( typeof window !== 'undefined' ) {
                    jQuery = require('jquery');
                } else {
                    jQuery = require('jquery')(root);
                }
            }
            factory(jQuery);
            return jQuery;
        };
    } else {
        //Browser globals
        factory(jQuery);
    }
}(function ($) {
    $.emoticons = function(parameter,getApi) {
        if(typeof parameter == 'function'){ //重載
            getApi = parameter;
            parameter = {};
        }else{
            parameter = parameter || {};
            getApi = getApi||function(){};
        }
        var defaults = {
            'prefix':'widget',
            'publisherCls':'publisher',
            'triggerCls':'trigger',
            'activeCls':'active',
            'path':'/img/im/emoticons/',
            'list':emoticonsList,
            'top':0,
            'left':0
        };
        var options = $.extend({}, defaults, parameter);
        var _api = {};
        var $document = $(document);
        var $emoticon = $('#im_emoticons');
        var _hash = {};
        $.each(options.list,function(index,item){
            _hash[item.title] = options.path+item.url;
            $emoticon.append('<img title="'+item.title+'" src="'+_hash[item.title]+'"/>');
        });
        //初始化
        getApi(_api);
        return this;
    };
}));

var emoticonsList = [{title:'微笑',url:'weixiao.gif'},{title:'嘻嘻',url:'xixi.gif'},{title:'哈哈',url:'haha.gif'},{title:'可愛',url:'keai.gif'},{title:'可憐',url:'kelian.gif'},{title:'挖鼻',url:'wabi.gif'},{title:'吃驚',url:'chijing.gif'},{title:'害羞',url:'haixiu.gif'},{title:'擠眼',url:'jiyan.gif'},{title:'閉嘴',url:'bizui.gif'},{title:'鄙視',url:'bishi.gif'},{title:'愛你',url:'aini.gif'},{title:'淚',url:'lei.gif'},{title:'偷笑',url:'touxiao.gif'},{title:'親親',url:'qinqin.gif'},{title:'生病',url:'shengbing.gif'},{title:'太開心',url:'taikaixin.gif'},{title:'白眼',url:'baiyan.gif'},{title:'右哼哼',url:'youhengheng.gif'},{title:'左哼哼',url:'zuohengheng.gif'},{title:'噓',url:'xu.gif'},{title:'衰',url:'shuai.gif'},{title:'吐',url:'tu.gif'},{title:'哈欠',url:'haqian.gif'},{title:'抱抱',url:'baobao.gif'},{title:'怒',url:'nu.gif'},{title:'疑問',url:'yiwen.gif'},{title:'饞嘴',url:'chanzui.gif'},{title:'拜拜',url:'baibai.gif'},{title:'思考',url:'sikao.gif'},{title:'汗',url:'han.gif'},{title:'困',url:'kun.gif'},{title:'睡',url:'shui.gif'},{title:'錢',url:'qian.gif'},{title:'失望',url:'shiwang.gif'},{title:'酷',url:'ku.gif'},{title:'色',url:'se.gif'},{title:'哼',url:'heng.gif'},{title:'鼓掌',url:'guzhang.gif'},{title:'暈',url:'yun.gif'},{title:'悲傷',url:'beishang.gif'},{title:'抓狂',url:'zhuakuang.gif'},{title:'黑線',url:'heixian.gif'},{title:'陰險',url:'yinxian.gif'},{title:'怒罵',url:'numa.gif'},{title:'互粉',url:'hufen.gif'},{title:'書呆子',url:'shudaizi.gif'},{title:'憤怒',url:'fennu.gif'},{title:'感冒',url:'ganmao.gif'},{title:'心',url:'xin.gif'},{title:'傷心',url:'shangxin.gif'},{title:'豬',url:'zhu.gif'},{title:'熊貓',url:'xiongmao.gif'},{title:'兔子',url:'tuzi.gif'},{title:'OK',url:'ok.gif'},{title:'耶',url:'ye.gif'},{title:'GOOD',url:'good.gif'},{title:'NO',url:'no.gif'},{title:'贊',url:'zan.gif'},{title:'來',url:'lai.gif'},{title:'弱',url:'ruo.gif'},{title:'草泥馬',url:'caonima.gif'},{title:'神馬',url:'shenma.gif'},{title:'囧',url:'jiong.gif'},{title:'浮云',url:'fuyun.gif'},{title:'給力',url:'geili.gif'},{title:'圍觀',url:'weiguan.gif'},{title:'威武',url:'weiwu.gif'},{title:'話筒',url:'huatong.gif'},{title:'蠟燭',url:'lazhu.gif'},{title:'蛋糕',url:'dangao.gif'},{title:'發(fā)紅包',url:'fahongbao.gif'}];

六.備注

upload.js需要使用自己的AppKey
fileExts: ['JPG','PNG','JPGE','GIF']
...后續(xù)再加晚树,今天先到這里

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姻采,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子爵憎,更是在濱河造成了極大的恐慌慨亲,老刑警劉巖婚瓜,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異刑棵,居然都是意外死亡巴刻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門蛉签,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胡陪,“玉大人,你說我怎么就攤上這事碍舍∧” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵片橡,是天一觀的道長愚隧。 經(jīng)常有香客問我,道長锻全,這世上最難降的妖魔是什么狂塘? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮鳄厌,結(jié)果婚禮上荞胡,老公的妹妹穿的比我還像新娘。我一直安慰自己了嚎,他們只是感情好泪漂,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著歪泳,像睡著了一般萝勤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上呐伞,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天敌卓,我揣著相機(jī)與錄音,去河邊找鬼伶氢。 笑死趟径,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的癣防。 我是一名探鬼主播蜗巧,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蕾盯!你這毒婦竟也來了幕屹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎望拖,沒想到半個月后迅腔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡靠娱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了掠兄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片像云。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蚂夕,靈堂內(nèi)的尸體忽然破棺而出迅诬,到底是詐尸還是另有隱情,我是刑警寧澤婿牍,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布侈贷,位于F島的核電站,受9級特大地震影響等脂,放射性物質(zhì)發(fā)生泄漏俏蛮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一上遥、第九天 我趴在偏房一處隱蔽的房頂上張望搏屑。 院中可真熱鬧,春花似錦粉楚、人聲如沸辣恋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伟骨。三九已至,卻和暖如春燃异,著一層夾襖步出監(jiān)牢的瞬間携狭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工回俐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暑中,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓鲫剿,卻偏偏與公主長得像鳄逾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子灵莲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容