Web SDK V1.1.1 集成说明


注意:

这是 Web SDK V1.1.1 版本的集成说明,仅供未升级 Web SDK 版本的老用户参考。如果您是 Web SDK 的新用户,请集成 Web SDK 的最新版本(V1.1.2及以上),并阅读最新版集成说明:Web IM 介绍

Web IM 介绍

环信Web IM Demo 展示了怎样使用环信 Web IM SDK 快速创建一个完整的类微信网页聊天示例。展示的功能包括:登录、登出、操作好友、收发个人消息、群组消息。

环信 Web IM 源代码已在 GitHub 上开源供开发者下载 https://github.com/easemob/web-im,以帮助开发者更好的学习了解环信 SDK。

也可登录 http://webim.easemob.com 对 Web IM 进行体验,账号为环信 Demo 的账号(与 Android、iOS 的 Demo 账号相通)。

  1. 下载环信 Web IM 及 SDK:下载
  2. 解压缩 WEB-IM.zip 后会得到以下目录结构:

Web IM SDK目录结构

运行之前,需要调整 AppKey,打开 static/js/easemob.im.config.js,找到:

appKey : 'easemob-demo#chatdemoui'

将这里的值做相应调整。

运行方式有两种:

  • 直接使用浏览器打开 index.html 文件。(注:ie8、9需要使用第二种方式)
  • 将解压缩的文件夹目录部署到 web 服务器通过 URL 访问 index.html。

功能操作页面如下:

登录:

登录可以使用 APP 用户的账号和密码。

登录web IM demo

发送文本及表情消息:

发送文本及表情消息

发送图片消息页面:

发送图片消息

个人聊天页面:

与好友聊天

群组聊天:

群组聊天

操作菜单:

操作菜单

申请添加好友通知:

收到添加为好友请求通知,可以进行“同意”、“拒绝”处理,默认为双向添加互为好友。

申请添加好友通知

删除好友操作:

输入要删除的好友账号。

删除好友

easemob webim sdk 已支持如下功能:

1. SDK 本身已支持 IE8+、FireFox10+、Chrome15+、Safari6+ 之间文本、表情、图片、音频消息相互发送;

2. SDK 支持 Web 端之间,Web 端与 Android 端/iOS 端相互添加、删除好友功能。

3. SDK 支持与 iOS、Android SDK 之间相互发送文本、图片、音频、地址消息。

4. SDK 提供的公共方法参见解压后 SDK 目录中的 quickstart.md。

5. SDK 对于消息的处理方式如下:

1)文本消息,直接发送,接收方接收到为文本消息。

2)表情消息,SDK 得到表情对应的编码后,发送的文本消息,接收方接收到后处理根据编码还原表情。

3)图片消息,SDK 上传图片到聊天服务器,然后发送图片基本信息消息,消息中带有发送方上传的图片 URL 等,接收方根据图片 URL、secret 和自身的登录信息,以流的形式从服务器上下载图片到本地显示。

4)音频消息,SDK 上传音频到聊天服务器,然后发送音频基本消息消息,消息中含有发送方上传的音频 URL 等,接收房根据音频 URL、secret 和自身的登录信息,以流的形式从服务器上下载音频到本地播放。

6. 提供 demo,方便大家参考,已实现聊天添加/删除好友/群组功能。

7. 目前ie10+、chrome、safari、firefox等各浏览器均已支持直接播放MP3格式。

浏览器支持列表:

●:支持

○:不支持

Browser\Func Text Message Emotion Message Picture Message Audio Message Add Friend Delete Friend
IE8
IE9
IE10
IE11
FireFox10+
Chrome15+
Safari5X
Safari6X
Safari7X
Safari8X

备注:

  • demo中允许发送的图片格式:GIF、PNG、JPG、BMP;
  • demo中允许发送的音频格式:MP3、WMA、WAV、AMR、AVI。

集成方式


  1. 下载 web-im-1.1.1.zip 解压后需将 webim-im-1.1.1 文件夹拷贝到系统相应的目录下。
  2. 新建 html 文件并参考webim-im-1.1.1下index.html引入相关脚本。
<!--sdk相关的js-->
<script type='text/javascript' src='static/sdk/strophe.js'></script>
<script type="text/javascript" src="static/sdk/easemob.im-1.1.1.js"></script>
<script type="text/javascript" src="static/sdk/easemob.im.shim.js"></script>
<!--webim相关配置-->
<script type="text/javascript" src="static/js/easemob.im.config.js"></script>

下面以用户登录、发送文本消息、操作好友为例引导用户完成 Web IM SDK 的简单使用。

配置项在static/js/easemob.im.config.js文件内

xmppURL: 'im-api.easemob.com',    // 环信xmppURL,1.1.0版本之前的客户需配置成:'ws://im-api.sandbox.easemob.com/ws/' 或 'wss://im-api.easemob.com/ws/'

apiURL: 'http://a1.easemob.com',          // rest api地址

appkey: "easemob-demo#chatdemoui",        // appkey

https : false,                            // 是否使用https

multiResources: false                     // 是否开启多页面同步收消息

注:建议xmppURL、apiURL、https三个参数统一,否则ie10以下会报拒绝访问的错误。

例:

  • https: false
xmppURL: 'im-api.easemob.com',    // 环信xmppURL,1.1.0版本之前的客户需配置成:'ws://im-api.sandbox.easemob.com/ws/'

apiURL: 'http://a1.easemob.com',          // rest api地址

appkey: "easemob-demo#chatdemoui",        // appkey

https : false,                            // 是否使用https

multiResources: false                     // 是否开启多页面同步收消息

  • https: true
xmppURL: 'im-api.easemob.com',    // 环信xmppURL,1.1.0版本之前的客户需配置成:'wss://im-api.sandbox.easemob.com/ws/'

apiURL: 'https://a1.easemob.com',          // rest api地址

appkey: "easemob-demo#chatdemoui",        // appkey

https : true,                            // 是否使用https

multiResources: false                     // 是否开启多页面同步收消息

根据用户名/密码/昵称注册环信 Web IM。新建注册页面 html 元素。

<div id="regist-box">
	user<input type="text" id="usename" />
	password<input type="password" id="password" />
	nickname<input type="text" id="nickname" />
	<input type="button" value="regist"  id="regist" />
</div>

编写注册按钮调用 js 函数。

$("#regist").on('click', function() {
	var options = {
		username : 'zjj8',
		password : '123456',
		appKey : 'easemob-demo#chatdemoui',
		success : function(result) {
				//注册成功;
		},
		error : function(e) {
				//注册失败;
		}
	};
	Easemob.im.Helper.registerUser(options);
  });

根据用户名/密码登录环信 Web IM。新建用户名密码 html 元素。

<div id="login-box">
	user<input type="text" id="usename"/>
	password<input type="password" id="password"/>
	<input type="button" value="login" id="login" />
</div>

编写登录按钮调用 js 函数。

$('login').on('click', function() {
	//预留空现实
})

首先获取用户名/密码 input 框中的输入值。

var username = $("#usename").val();
var pass = $("#password").val();

创建一个新的连接。

var conn = new Easemob.im.Connection();

初始化连接。

conn.init({
     //预留空现实
 });

在 init 方法中添加 onOpened 回调函数,处理登录信息。

//当连接成功时的回调方法
onOpened : function() {
	alert("成功登录");
	conn.setPresence();
}

登录完整 JS 调用代码如下。

$(function() {
        var conn = null;
        conn = new Easemob.im.Connection();
        $('body').on('click', '#login', function() {
                var username = $("#usename").val();
                var pass = $("#password").val();
                conn.open({
                        user : username,
                        pwd : pass,
                        appKey : 'easemob-demo#chatdemoui'
                });
        })
        conn.init({
                onOpened : function() {
                        alert("成功登录");
                        conn.setPresence();
                }
        });
});

发送文本消息

创建消息 div。

<div id="content">
	消息内容<textarea id="text"></textarea>
    sendTo <input type="text" id="sendto"/>
    <button id="send">发送</button>
</div>

编写发送文本消息 js 函数。

$("#send").on('click',function(){
	sendText();
	});
var sendText = function() {
	var msg = $('textarea').val();
	var to = $("#sendto").val();
	var options = {
		to : to,
		msg : msg,
		type : "chat"
	};
    //发送文本消息接口
	conn.sendTextMessage(options);
};

登录成功后发送文本消息完整 JS 调用代码如下。

$(function(){
		var conn = null;
		conn = new Easemob.im.Connection();
		$('body').on('click','#login',function(){
			var username = $("#usename").val();
			var pass = $("#password").val();
			conn.open({
				user : username,
				pwd : pass,
				appKey : 'easemob-demo#chatdemoui'
			});
		})
		conn.init({
			onOpened : function(){
				alert("成功登录");
				conn.setPresence();
			},
			onTextMessage : function(message){
				console.log(message);
				alert("发送消息成功");
			}
		})	
		$("#send").on('click',function(){
			sendText();
		})
		var sendText = function() {
			var msg = $('textarea').val();
			var to = $("#sendto").val();
			var options = {
				to : to,
				msg : msg,
				type : "chat"
			};
			conn.sendTextMessage(options);
		};
	});

处理文本消息

登录成功后收到文本消息的处理方法需要在 con.init 方法中调用 onTextMessage 回调函数。

conn.init({
  //收到文本消息时的回调方法
  onTextMessage : function(message){
	//console.log(message);
	//alert("发送消息成功");		
   var from = message.from;//消息的发送者
   var mestype = message.type;//消息发送的类型是群组消息还是个人消息
   var messageContent = message.data;//文本消息体
   if (mestype == 'groupchat') {
		//进行群组消息页面处理	
	} else {
		//进行个人消息页面处理	
	}
 }
});

获取好友列表

在 onOpened : function(){}; 中添加 getRoster 回调方法,添加获取当前登录人好友列表。

conn.init({
	onOpened : function(){
		//alert("成功登录");
		//conn.setPresence();
		conn.getRoster({
	       success : function(roster) {
	      		// 获取当前登录人的好友列表
	      		for ( var i in roster) {
		  		  var ros = roster[i]; //好友的对象
		          //ros.name为好友名称
	     		 }
			}
		});
	}
});

将数组中的好友名称放入对应的 html 相应元素显示即可。

添加好友

邀请发起方

添加发起方,获取要添加好友名称,例如 addfridentId 为要添加的好友的 id。

//addfridentId为页面上要添加好友的输入框html元素id值。
var user = $('#addfridentId').val();

添加好友按钮点击时调用 startAddFriend 函数。

var startAddFriend = function() {
  var user = $('#addfridentId').val();
  //发送添加好友请求
  conn.subscribe({
	to : user,
	message : "加个好友呗"
  });
}

邀请接受方

被添加方,在 con.init 方法中调用 handlePresence 回调方法。

conn.init({
	//收到联系人订阅请求的回调方法
	onPresence : function(message) {
		handlePresence(message);
	}
});


//easemobwebim-sdk中收到联系人订阅请求的处理方法,具体的type值所对应的值请参考xmpp协议规范
var handlePresence = function(e) {
//(发送者希望订阅接收者的出席信息)
	if (e.type == 'subscribe') {
		//同意添加好友操作的实现方法
		conn.subscribed({
			to : user,
		    message : "[resp:true]"
		});
		
		//拒绝添加好友的方法处理
		//conn.unsubscribed({
			//to : user,
			//message : "rejectAddFriend"
		//});
	}
};

删除好友

删除好友,首先获取好友名称,调用 removeRoster 方法。例如删除按钮触发时调用 delFriend 函数。

var delFriend = function() {
	var user = $('#delfridentId').val();//获取要删除好友的名称
	conn.removeRoster({
		to : user,
		success : function() {
	 	 conn.unsubscribed({
			to : user
	     });
		},
		error : function() {
	   		//删除操作失败
		}
    });
}

当用户退出登录时需要调用 con.onClosed 回调函数。

conn.init({
	//当连接关闭时的回调方法
	onClosed : function() {
		conn.clear();
		conn.onClosed();
	}
});

初始化


var conn = new Easemob.im.Connection();
conn.init({
    https : true,//非必填,url值未设置时有效,优先采用url配置的参数。默认采用http连接,地址为‘http://im-api.easemob.com/http-bind/’,启用https时传递此值,地址为:‘https://im-api.easemob.com/http-bind/’
    url : 'http://im-api.easemob.com/http-bind/',//非必填,默认聊天服务器地址,
    domain : 'aa.com',//非必填,默认:‘easemob.com’
    wait : '60',//非必填,连接超时,默认:60,单位seconds
    onOpened : function() {
        curUserId = conn.context.userId;
        //查询好友列表
        conn.getRoster(....);
    },
    onClosed : function() {
        //处理登出事件
    },
    onTextMessage : function(message) {
        /**处理文本消息,消息格式为:
            {	type :'chat',//群聊为“groupchat”
                from : from,
                to : too,
                data : { "type":"txt",
                    "msg":"hello from test2"
                }
            }
        */
        handleTextMessage(message);
    },
    onEmotionMessage : function(message) {
        /*处理表情消息,消息格式为:
            {	type :'chat',//群聊为“groupchat”
                from : from,
                to : too,
                data : [{ "type":"txt",
                    "msg":"hello from test2"
                },
                { "type":"emotion",
                  "msg":"data:image/png;base64, ……"//图片的base64编码
                }]
            }
        */
        handleEmotion(message);
    },
    onPictureMessage : function(message) {
        /**处理图片消息,消息格式为:
            {	type :'chat',//群聊为“groupchat”
                from : "test1",
                to : "test2",
                url : "http://s1.easemob.com/weiquan2/a2/chatfiles/0c0f5f3a-e66b-11e3-8863-f1c202c2b3ae",
                secret : "NSgGYPCxEeOou00jZasg9e-GqKUZGdph96EFxJ4WxW-qkxV4",
                filename : "logo.png",
                thumb : "http://s1.easemob.com/weiquan2/a2/chatfiles/0c0f5f3a-e66b-11e3-8863-f1c202c2b3ae",
                thumb_secret : "0595b06a-ed8b-11e3-9b85-93fade9c198c",
                file_length : 42394,
                width : 280,
                height : 160,
                filetype : "image/png",
                accessToken :"YWMtjPPoovCqEeOQs7myPqqaOwAAAUaqNH0a8rRj4PwJLQju6-S47ZO6wYs3Lwo"
            }
        */

        handlePictureMessage(message);
    },
    onAudioMessage : function(message) {
        /**处理音频消息,消息格式为:
           {	type :'chat',//群聊为“groupchat”
                from : "test1",
                to : "test2",
                url : "http://s1.easemob.com/weiquan2/a2/chatfiles/0c0f5f3a-e66b-11e3-8863-f1c202c2b3ae",
                secret :"NSgGYPCxEeOou00jZasg9e-GqKUZGdph96EFxJ4WxW-qkxV4",
                filename : "风雨无阻.mp3",
                length :45223,
                file_length : 304,
                filetype : "mp3",
                accessToken :"YWMtjPPoovCqEeOQs7myPqqaOwAAAUaqNH0a8rRj4PwJLQju6-S47ZO6wYs3Lwo"
            }
        */
        handleAudioMessage(message);
    },
    //收到联系人订阅请求的回调方法
    onPresence : function (message){
        /**
            {
                from: "l2",
                fromJid: "easemob-demo#chatdemoui_l2@easemob.com",
                status: "下午11:44:47",
                to: "test1",
                toJid: "easemob-demo#chatdemoui_test1@easemob.com/13856640471403797405809685",
                type: "subscribed"
            }
        */
        handlePresence(message);
    },
    //收到联系人信息的回调方法
    onRoster : function (message){
        /**
            [{
                groups: [{0: "default",
                        length: 1}],
                jid: "easemob-demo#chatdemoui_l2@easemob.com",
                name: "l2",
                subscription: "to"
            }]
        */
        handleRoster(message);
    },
    onError : function(e) {
        //异常处理
        alert(e.msg);
    }
});

支持 username/password 和 username/token 登录两种方式,SDK 中会根据传入的参数进行自动选择是否登录 usergrid,获取登录成功的 token 后再进行登录聊天,如果使用 token 的打开连接将跳过登录 usergird,直接登录 IM 服务器。

//用户名
var user = $("#username").val();
//密码
var pass = $("#password").val();
if (user == '' || pass == '') {
    alert("请输入用户名和密码");
    return;
}
conn.open({
    user : user,
    pwd : pass,
    appKey : 'easemob-demo#chatdemoui'//开发者APPKey
    //accessToken : 'YWMt8bfZfFk5EeSiAzsQ0OXu4QAAAUpoZFOMJ66ic5m2LOZRhYUsRKZWINA06HI'
});

单聊


查询好友列表

查询好友列表时,要注意 subscription(both、to、from)为不同值的处理,此处默认 both 和 to 的为好友,开发者自定义处理,保持跟 APP 端处理一致即可。

conn.getRoster({
    success : function(roster) {
        //获取好友列表,并进行好友列表渲染,roster格式为:
        /** [
                {
                    jid:"asemoemo#chatdemoui_test1@easemob.com",
                    name:"test1",
                    subscription: "both"
                },
                {
                    jid:"asemoemo#chatdemoui_test2@easemob.com",
                    name:"test2",
                    subscription: "from"
                }
            ]
        */
        for(var i in roster){
            var ros = roster[i];    
            //ros.subscriptio值为both/to为要显示的联系人,此处与APP需保持一致,才能保证两个客户端登录后的好友列表一致
            if(ros.subscription =='both' || ros.subscription=='to'){
                newroster.push(ros);
            }
        }
        if (newroster.length >=0) {
            buildContactDiv("contractlist", newroster);//页面处理
            if (newroster.length > 0) {
                setCurrentContact(newroster[0].name);//页面处理将第一个联系人作为当前聊天div
            }
        }
        //conn.setPresence();
    },    
});

添加好友

通过 SDK 的 subscribe 和 unsubscribe 进行添加或者删除好友操作,登录用户通过注册 onPresence,监听对方的添加或者删除好友请求,并做相应的处理。

//easemobwebim-sdk中收到联系人订阅请求的处理方法,具体的type值所对应的值请参考xmpp协议规范
var handlePresence = function (e){
	//(发送者希望订阅接收者的出席信息),即别人申请加你为好友
	if (e.type == 'subscribe') {
		//若e.status中含有[resp:true],则表示为对方同意好友后反向添加自己为好友的消息,demo中发现此类消息,默认同意操作,完成双方互为好友;如果不含有[resp:true],则表示为正常的对方请求添加自己为好友的申请消息。
		......
	}
	//(发送者允许接收者接收他们的出席信息),即别人同意你加他为好友
	if (e.type == 'subscribed') {
		......
	}
	//(发送者取消订阅另一个实体的出席信息),即删除现有好友
	if (e.type == 'unsubscribe') {
		.......
	}
	//(订阅者的请求被拒绝或以前的订阅被取消),即对方单向的删除了好友
	if (e.type == 'unsubscribed') {
		.......
	}
};

申请添加对方为好友

//主动申请添加对方为好友
var startAddFriend = function startAddFriend(){
    //对方用户账号
    var user = $("addfridentId").val();
    //请求添加对方为好友
    conn.subscribe({
		to : user,
		message : "加个好友呗-" + getLoacalTimeString()
	});
    return;
};
var getLoacalTimeString = function getLoacalTimeString() {
		var date = new Date();
		var time = date.getHours() + ":" + date.getMinutes() + ":"
				+ date.getSeconds();
		return time;
	}

对方收到请求,同意或者拒绝

//对方收到请求加为好友,接受请求
$('#confirm-block-footer-confirmButton').click(function() {
	//同意好友请求
	agreeAddFriend(e.from);//e.from用户名
	//反向添加对方好友
	conn.subscribe({
		to : e.from,
		message : "[resp:true]"
	});
}
//同意
var agreeAddFriend = function agreeAddFriend(connection,who,jid){
   conn.subscribed({
			to : user,
			message : "[resp:true]"//同意后发送反加对方为好友的消息,反加消息标识[resp:true]
		});
};

//对方收到请求加为好友,拒绝请求
$('#confirm-block-footer-cancelButton').click(function() {
	rejectAddFriend(e.from);//拒绝加为好友
});
//拒绝
var rejectAddFriend = function(user) {
	conn.unsubscribed({
		to : user,
		message : getLoacalTimeString()
	});
};

对于好友的分组,添加好友时在 addroster 可以指定 group 属性(默认为:default 组),添加好友成功后,好友列表渲染时,根据好友的 group 属性进行分组渲染,实现类似其他聊天工具的自定义好友分组管理的功能。

删除好友

取消订阅,同时将对方从自己的好友列表上删除掉。

var delFriend = function(user) {
	conn.removeRoster({
		to : user,
		groups : [ 'default' ],
		success : function() {
			conn.**unsubscribed**({
				to : user
			});
		}
	});
};

发送文本(表情)聊天消息

//发送文本消息
conn.sendTextMessage({
    to : to,//用户登录名,SDK根据appkey和domain组织jid,如easemob-demo#chatdemoui_**TEST**@easemob.com,中"to:TEST",下同
    msg :'hello world!' //文本消息
    //ext :{"extmsg":"extends messages"}//用户自扩展的消息内容(群聊用法相同)
});

//发送表情消息,调用接口同文本消息
conn.sendTextMessage({
    to : to,
    msg :'hello world![(*)][(#)]' //文本消息+表情
    //ext:{"extmsg":"extends messages"}//用户自扩展的消息内容(群聊用法相同)
});

发送命令消息

//发送cmd消息
conn.sendCmdMessage({
    to : to,//用户登录名,SDK根据appkey和domain组织jid,如easemob-demo#chatdemoui_**TEST**@easemob.com,中"to:TEST",下同
    msg :'hello world!' //文本消息
    action : 'action' //用户自定义,cmd消息必填
    //ext :{"extmsg":"extends messages"}//用户自扩展的消息内容(群聊用法相同)
});

发送图片消息

发送图片消息SDK自动分两步完成:

  1. 上传图片文件到服务器,并得到服务返回的图片信息等;
  2. 发送图片消息,消息体包含图片的基本信息、服务器路径、secret 等,接收方初始化连接中的 onPictureMessage 的格式,根据图片消息内容到服务器下载图片,并进行显示。
function sendPic() {
    //图片接收者,如“test1”
    var to = curChatUserId;
    if (to == null) {
        alert("请选择联系人");
        return;
    }
    //fileInputId:文件选择输入框的Id,SDK自动根据ID自动获取文件对象(含图片,或者其他类型文件)
    var fileObj = Easemob.im.Helper.getFileUrl(fileInputId);
    if (fileObj.url == null || fileObj.url == '') {
        alert("请选择发送图片");
        return;
    }
    var filetype = fileObj.filetype;
    var filename = fileObj.filename;
    if (filetype in  {
                    "jpg" : true,
                    "gif" : true,
                    "png" : true,
                    "bmp" : true
                    }) {
        var opt = {
            fileInputId : fileInputId,
            to : to,
            onFileUploadError : function(error) {
                //处理图片上传失败
            },
            onFileUploadComplete : function(data) {
                //处理图片上传成功,如本地消息显示
            }
           // ext:{"extmsg":"extends messages"}//用户自扩展的消息内容(群聊用法相同)
        };
        conn.sendPicture(opt);
        return;
    }
    alert("不支持此图片类型" + filetype);
};

发送音频消息

SDK 处理同发送图片消息,分两步:

  1. 上传音频文件到服务器,得到音频文件的信息;
  2. 发送音频消息给接收方,消息体包含音频的基本信息、下载路径和 secret 信息等,接收方收到消息后,根据消息体内部的音频下载路径和 secret 路径,下载音频并进行显示。
function sendAudio () {
    var to = curChatUserId;
    if (to == null) {
        alert("请选择联系人");
        return;
    }
    var fileObj = Easemob.im.Helper.getFileUrl(fileInputId);
    if (fileObj.url == null || fileObj.url == '') {
        alert("请选择发送音频");
        return;
    }
    var filetype = fileObj.filetype;
    var filename = fileObj.filename;
    if (filetype in {
                "mp3" : true,
                "wma" : true,
                "wav" : true,
                "avi" : true
                })
    {
        var opt = {
            fileInputId : fileInputId,
            to : to,
            onFileUploadError : function(error) {
                //处理上传音频失败
            },
            onFileUploadComplete : function(data) {
                //处理上传音频成功,如本地消息提示发送成功
            }
            //ext:{"extmsg":"extends messages"}//用户自扩展的消息内容(群聊用法相同)
        };
        conn.sendAudio(opt);
        return;
    }
    alert("不支持此音频类型" + filetype);
};

接收消息

注册接收消息。

conn.init({
	onTextMessage : function(message) {        },//收到文本消息处理动作
    onEmotionMessage : function(message) {        },//收到表情消息处理动作
    onPictureMessage : function(message) {         },//收到图片消息处理动作
    onAudioMessage : function(message) {        }, //收到语音消息处理动作
	...
});

处理消息

conn.init() 中注册不同消息接收 handler 之后,可自行解析消息体,定位聊天好友,并追加到与其聊天窗口。具体参考 webim.easemob.com 效果,消息体格式参见前章节:初始化连接。

注:对于图片、语音消息需要先进行下载,然后进行显示或者播放处理。如下(下载图片,音频同):

var handlePictureMessage = function(message) {
var filename = message.filename;//文件名称,带文件扩展名
var from = message.from;//文件的发送者
var ext = message.ext;//获取用户的扩展信息(群聊用法相同)
var mestype = message.type;//消息发送的类型是群组消息还是个人消息
......
...
var options = message;
// 图片消息下载成功后的处理逻辑
options.onFileDownloadComplete = function(response, xhr) {
	var objectURL = window.URL.createObjectURL(response);
	img = document.createElement("img");
	img.onload = function(e) {
		img.onload = null;
		window.URL.revokeObjectURL(img.src);
	};
	img.onerror = function() {
		img.onerror = null;
		if (typeof FileReader == 'undefined') {
			img.alter = "当前浏览器不支持blob方式";
			return;
		}
		img.onerror = function() {
			img.alter = "当前浏览器不支持blob方式";
		};
		var reader = new FileReader();
		reader.onload = function(event) {
			img.src = this.result;
		};
		reader.readAsDataURL(response);
	}
	img.src = objectURL;
	var pic_real_width = options.width;
	......
	...
};
options.onFileDownloadError = function(e) {
	appendMsg(from, contactDivId, e.msg + ",下载图片" + filename + "失败");
};
Easemob.im.Helper.download(options);

历史消息

SDK 暂不具有缓存历史消息功能,demo 中聊天窗口只能显示,当前登录后会话实时在聊天信息,不能查看历史消息,可以对登录后的聊天信息进行清除操作。

新消息提示

SDK 在收到新消息是会直接转发给登录用户,接收到消息后,demo 中会在好友或者群组的后面显示红色消息数,具体样式开发者可自行处理。

群聊


//根据roomId查询room成员列表
var queryOccupants = function queryOccupants(roomId) {
    var occupants = [];//存放成员容器
    //查询获取room信息
    conn.queryRoomInfo({
        roomId : roomId,
        success : function(occs) {
            if (occs) {
                for ( var i = 0; i < occs.length; i++) {
                    occupants.push(occs[i]);
                }
            }
            //查询获取room成员信息
            conn.queryRoomMember({
                roomId : roomId,
                success : function(members) {
                    if (members) {
                        for ( var i = 0; i < members.length; i++) {
                            occupants.push(members[i]);
                        }
                    }
                }
            });
        }
    });
};
//发送文本消息
conn.sendTextMessage({
    to : to, //目标群组id,如要把消息发到群id是169646349464111860的群中,to:'169646349464111860',下同
    type : 'groupchat',
    msg :'hello world!' //文本消息
	
});

//发送表情消息,调用接口同文本消息
conn.sendTextMessage({
    to : to,
    type : 'groupchat',
    msg :'hello world![(*)][(#)]' //文本消息+表情
});

发送图片消息 SDK 自动分两步完成:

  1. 上传图片文件
  2. 发送图片消息初始化连接中的 onPictureMessage 的格式
//发送图片消息时调用方法
var sendPic = function() {
    var to = curChatUserId;
    if (to == null) {
        return;
    }
    // Easemob.im.Helper.getFileUrl为easemobwebim-sdk获取发送文件对象的方法,fileInputId为 input 标签的id值
    var fileObj = Easemob.im.Helper.getFileUrl(fileInputId);
    if (fileObj.url == null || fileObj.url == '') {
        alert("请选择发送图片");
        return;
    }
    var filetype = fileObj.filetype;
    var filename = fileObj.filename;
    if (filetype in pictype) {
        document.getElementById("fileSend").disabled = true;
        document.getElementById("cancelfileSend").disabled = true;
        var opt = {
            type:'chat',
            fileInputId : fileInputId,
            to : to,
            onFileUploadError : function(error) {
                //处理图片上传失败
            },
            onFileUploadComplete : function(data) {
                //关闭文件选择窗口
                $('#fileModal').modal('hide');
                //本地缩略图
                var file = document.getElementById(fileInputId);
                if (file && file.files) {
                    var objUrl = getObjectURL(file.files[0]);
                    if (objUrl) {
                        var img = document.createElement("img");
                        img.src = objUrl;
                        img.width = maxWidth;
                    }
                }
            
            }
        };
        //判断是否为群组标识
        if (curChatUserId.indexOf(groupFlagMark) >= 0) {
            opt.type = 'groupchat';//群组标识符
            opt.to = curRoomId;
        }
        conn.sendPicture(opt);
        return;
    }
    alert("不支持此图片类型" + filetype);
};

SDK 处理同群发送图片消息,分两步:

  1. 上传音频
  2. 发送消息
//发送音频消息时调用的方法
var sendAudio = function() {
    var to = curChatUserId;
    if (to == null) {
        alert("请选择联系人");
        return;
    }
    //利用easemobwebim-sdk提供的方法来构造一个file对象
    var fileObj = Easemob.im.Helper.getFileUrl(fileInputId);
    if (fileObj.url == null || fileObj.url == '') {
            alert("请选择发送音频");
        return;
    }
    var filetype = fileObj.filetype;
    var filename = fileObj.filename;
    if (filetype in audtype) {
        document.getElementById("fileSend").disabled = true;
        document.getElementById("cancelfileSend").disabled = true;
        var opt = {
            type:"chat",
            fileInputId : fileInputId,
            to : to,//发给谁
            onFileUploadError : function(error) {
                //处理上传音频失败
            },
            onFileUploadComplete : function(data) {
                //处理上传音频成功,如本地消息提示发送成功
            }
        };
        //构造完opt对象后调用easemobwebim-sdk中发送音频的方法
        if (curChatUserId.indexOf(groupFlagMark) >= 0) {
            opt.type = 'groupchat';
            opt.to = curRoomId;
        }
        conn.sendAudio(opt);
        return;
    }
    alert("不支持此音频类型" + filetype);
};

群聊接收及处理消息同单聊,消息体与单聊消息根据 message 的 type 进行区分,单聊为:“chat”,群聊为:“groupchat”。根据消息的类型进行不同处理即可。

聊天室

conn.joinChatRoom({
    roomId: "roomId"//聊天室Id
});
conn.quitChatRoom({
    roomId: "roomId"//聊天室Id
});
conn.sendTextMessage({
    to: "to",//目标user
    msg: "msg",//文本消息
    type: "groupchat",//必填字段,无需修改
    roomType: "chatroom"//必填字段,无需修改
}); 

使用 handlePresence 方法中处理聊天室相关回调。

加入成功

if ( e.type == 'joinChatRoomSuccess' ) {\\  
}

加入失败

if ( e.type == 'joinChatRoomFailed' ) {\\  
}

聊天室被删除

if ( e.type == 'deleteGroupChat' ) {\\  
}
Easemob.im.EMOTIONS = {
    path: 'static/img/faces/'
    , map: {
        '[):]': 'ee_1.png',
        '[:D]': 'ee_2.png',
        '[;)]': 'ee_3.png',
        '[:-o]': 'ee_4.png',
        '[:p]': 'ee_5.png'
    }
}

退出


关闭连接。

//SDK关闭连接并处理连接状态为CLOSED
conn.close();

工具类说明


//返回表情JSON object,格式为:
    {
        "[):]" : "data:image/png;base64,iVBORw0K....==",
        "[:D]" : "data:image/png;base64,iVBORw0KGgoAAAANSUh....=="
    }

var emotion_json = Easemob.im.Helper.EmotionPicData;
Base64工具类

var base64  = Easemob.im.Helper.Base64;
var srcstr="ssss";
var base64str = base64.encode(srcstr);
var orgstr = base64.decode(srcstr);
//是否能上传file
var canupload = Easemob.im.Helper.isCanUploadFile;
//是否能下载file
var candownload = Easemob.im.Helper.isCanDownLoadFile ;
//是否设置header
var hasheader = Easemob.im.Helper.hasSetRequestHeader;
//是否设置mimetype
var hasmimetype = Easemob.im.Helper.hasOverrideMimeType;
//返回表情JSON,格式为:
{
    isemotion:true;
    body:[{
        type:txt,
        msg:ssss
    },
    {
        type:emotion,
        msg:imgdata
    }]
}

var emotionMsg = Easemob.im.Helper.parseTextMessage(message);
//返回fileinfo对象,格式为:
    {
        url : '',
        filename : '',
        filetype : ''
    }
var fileInfo = Easemob.im.Helper.getFileUrl(fileInputId);
//上传
var options={
    appName = 'chatdemoui',
    orgName = 'easemob-demo',
    accessToken = 'YWMtjPPoovCqEeOQs7myPqqaOwAAAUaqNH0a8rRj4PwJLQju6-S47ZO6wYs3Lwo',
    onFileUploadComplete:function(data){//upload file success },
    onFileUploadError:function(e){//upload file error },
    width:100,//only for pic
    heght:100//only for pic
}
Easemob.im.Helper.upload(options);
//下载
var options = {
    method:'GET',//default GET
    responseType:'blob',//default blob
    mimeType:'text/plain; charset=x-user-defined',//default
    url:'http://s1.easemob.com/weiquan2/a2/chatfiles/0c0f5f3a-e66b-11e3-8863-f1c202c2b3ae',
    secret = 'NSgGYPCxEeOou00jZasg9e-GqKUZGdph96EFxJ4WxW-qkxV4',
    accessToken = 'YWMtjPPoovCqEeOQs7myPqqaOwAAAUaqNH0a8rRj4PwJLQju6-S47ZO6wYs3Lwo',
    onFileUploadComplete:function(data){//upload file success },
    onFileUploadError:function(e){//upload file error },
}
Easemob.im.Helper.download(options);
//文件大小 
var options={
    fileInputId:'uploadfileinput'//文件输入框id
};
var fileSize = getFileSize(options.fileInputId);;
var options = {
    dataType:'text',//default
    success:function(){//handle request success},
    error :function(){//handle request error},
    type : 'post',//default 'post'
    url : 'http://s1.easemob.com/weiquan2/a2/chatfiles/0c0f5f3a-e66b-11e3-8863-f1c202c2b3ae',
    headers:'',//default {}
    data : '';//default null
};
Easemob.im.Helper.xhr(options);
var options = {
    appKey:'easemob-demo#chatdemoui',//default ''
    success:function(data){ //login success },//default emptyFn
    error : cunction(error){ //login error }, //default emptyFn
    user : 'test1', //default ''
    pwd : '123456'  //default ''
};
Easemob.im.Helper.login2UserGrid(options);
var options = {
	username : 'zjj8',
	password : '123456',
	appKey : 'easemob-demo#chatdemoui',
	success : function(result) {
		//注册成功
		},
		error : function(e) {
		//注册失败			
		}
	};
Easemob.im.Helper.registerUser(options);

当所有需要回调的地方接收到函数时,默认采用此函数。

var emptyFn = function() {};

常见问题


1. Web IM SDK 调用无效。

请检查 easemob.im-1.0.3.js 等相关文件引入的路径是否正确。

2. 是否支持 token 登录,是否支持 HTTPS?

支持。详情请查看 easemob.im-1.0.3.js 和 index.html 相关内容。

3. 是否支持重连?

暂不支持,可以使用 token 来实现重连。

4. 为什么登录后收不到消息?

登录之后需要设置在线状态,才能收到消息。请检查登录成功后是否调用过 conn.setPresence();。

5. 调试时经常报连接中断。

如果使用 alter 方式调试长时间没有进行操作时,连接超时后服务器会自动断开连接。同样断点等待时间过长时服务器也会断开连接。

6. Web IM 目前支持的浏览器类型及版本。

●:支持

○:不支持

Browser\Func Text Message Emotion Message Picture Message Audio Message Add Friend Delete Friend
IE7
IE8
IE9
IE10
IE11
FireFox10+
Chrome15+
Safari5X
Safari6X
Safari7X
Safari8X

7. 目前支持的 Picture Message 格式有哪些?

已知 Picture Message 格式支持:PNG、JPG、BMP。

8. 目前支持的 Audio Message 格式有哪些?

已知 Audio Message 格式支持:MP3、AMR。