商业化IM 客户端接口设计分析
对于刚接触IM(即时通讯)开发,通过阅读成熟的商业代码能够对即时通讯软件大体上有个认识,比如消息发送,消息接受,消息监听,群聊,单聊,聊天室。我这边直接拿[Gobelieve IM]源码来做剖析。IMService在代码层级里起着承上启下的作用,负责发送消息,接受消息(聊天消息,系统消息,控制命令消息(比如邀请VOIP,退群,加群)),消息在客户端转发,消息类型判断和分发,消息observer的增加和删除,IMService本身会根据业务需求实现handlers对接到数据传输层(socket)。Observers是衔接IMService和UI层。如果只侧重于UI层开发,重点是Observers,比如PeerMessageObserver是一对一聊天监听,GroupMessageObserver:群聊天监听,RoomMessageObserver:聊天室监听。
下面直接上接口代码来说,
@class IMessage;
IMessage 模型类的前置声明
@protocol IMPeerMessageHandler <NSObject>
-(BOOL)handleMessage:(IMMessage*)msg uid:(int64_t)uid;
-(BOOL)handleMessageACK:(int)msgLocalID uid:(int64_t)uid;
-(BOOL)handleMessageFailure:(int)msgLocalID uid:(int64_t)uid;
@end
一对一聊天的hanlder定义,IM有一个ACK的设计,用来显示消息是否已经通过服务器下发到对方客户端。具体的函数,handleMessage()接收到消息的处理函数。handleMessageACK()接收到消息已读的处理函数。 handleMessageFailure()接收到消息发送失败的处理函数。
@protocol IMGroupMessageHandler <NSObject> -(BOOL)handleMessage:(IMMessage*)msg;
-(BOOL)handleMessageACK:(int)msgLocalID gid:(int64_t)gid;
-(BOOL)handleMessageFailure:(int)msgLocalID gid:(int64_t)gid; -(BOOL)handleGroupNotification:(NSString*)notification;
@end
群聊天的hanlder定义,接口上比单聊多一个群状态改变的处理,还有就是单聊下发的是个人ID,群聊下发的是群聊ID,同样的函数,handleMessage()接收到消息的处理函数。handleMessageACK()接收到消息已读的处理函数。 handleMessageFailure()接收到消息发送失败的处理函数。handleGroupNotification(),处理群状态改变的函数,比如群名称改变,群成员改变,群解散等等事件。
@protocol IMCustomerMessageHandler <NSObject>
-(BOOL)handleCustomerSupportMessage:(CustomerMessage*)msg;
-(BOOL)handleMessage:(CustomerMessage*)msg;
-(BOOL)handleMessageACK:(CustomerMessage*)msg;
-(BOOL)handleMessageFailure:(CustomerMessage*)msg;
@end
客服聊天的handler定义。
@protocol LoginPointObserver <NSObject>
//用户在其他地方登陆
-(void)onLoginPoint:(LoginPoint*)lp;
@end
多端登录事件监听。
@protocol PeerMessageObserver <NSObject>
@optional
-(void)onPeerMessage:(IMMessage*)msg; //服务器ack
-(void)onPeerMessageACK:(int)msgLocalID uid:(int64_t)uid; //消息发送失败
-(void)onPeerMessageFailure:(int)msgLocalID uid:(int64_t)uid; //对方正在输入
-(void)onPeerInputing:(int64_t)uid; @end
一对一聊天的Observer的定义,提供了对输入状态监听的接口,用来实现,实时获取对方是否在编辑消息。
@protocol GroupMessageObserver <NSObject>
@optional
-(void)onGroupMessage:(IMMessage*)msg;
-(void)onGroupMessageACK:(int)msgLocalID gid:(int64_t)gid;
-(void)onGroupMessageFailure:(int)msgLocalID gid:(int64_t)gid; -(void)onGroupNotification:(NSString*)notification;
@end
群聊天的Observer的定义。
@protocol RoomMessageObserver <NSObject>
@optional
-(void)onRoomMessage:(RoomMessage*)rm;
-(void)onRoomMessageACK:(RoomMessage*)rm;
-(void)onRoomMessageFailure:(RoomMessage*)rm; @end
聊天室消息Observer的定义。
@protocol RTMessageObserver <NSObject> @optional
-(void)onRTMessage:(RTMessage*)rt; @end @protocol SystemMessageObserver <NSObject>
@optional
-(void)onSystemMessage:(NSString*)sm; @end
系统消息的Observer的定义。
@protocol CustomerMessageObserver <NSObject>
@optional
-(void)onCustomerMessage:(CustomerMessage*)msg;
-(void)onCustomerSupportMessage:(CustomerMessage*)msg; //服务器ack
-(void)onCustomerMessageACK:(CustomerMessage*)msg;
//消息发送失败
-(void)onCustomerMessageFailure:(CustomerMessage*)msg;
@end
客服消息的Observer的定义。
@protocol VOIPObserver <NSObject> -(void)onVOIPControl:(VOIPControl*)ctl; @end
支持整合VOIP功能的Observer的定义。
@interface IMService : TCPConnection
@property(nonatomic, copy) NSString *deviceID;
@property(nonatomic, copy) NSString *token;
@property(nonatomic) int64_t uid;
//客服app需要设置,普通app不需要设置
@property(nonatomic) int64_t appID; @property(nonatomic, weak)id<IMPeerMessageHandler> peerMessageHandler;//一对一聊天Handler
@property(nonatomic, weak)id<IMGroupMessageHandler> groupMessageHandler;//群聊handler
@property(nonatomic, weak)id<IMCustomerMessageHandler> customerMessageHandler;//客服handler 当前的IMService实现了三个(一对一聊天,群聊,客服)handler,可以按自己需要增加新的handler类型。消息统一在IMService做转发。
根据注册的Observer,传递到对该消息类型感兴趣的界面。 +(IMService*)instance;//IMService是单例的形式使用 -(BOOL)isPeerMessageSending:(int64_t)peer id:(int)msgLocalID;
-(BOOL)isGroupMessageSending:(int64_t)groupID id:(int)msgLocalID;
-(BOOL)isCustomerSupportMessageSending:(int)msgLocalID
customerID:(int64_t)customerID
customerAppID:(int64_t)customerAppID;
-(BOOL)isCustomerMessageSending:(int)msgLocalID storeID:(int64_t)storeID; -(BOOL)sendPeerMessage:(IMMessage*)msg;
-(BOOL)sendGroupMessage:(IMMessage*)msg;
-(BOOL)sendRoomMessage:(RoomMessage*)msg;
//顾客->客服
-(BOOL)sendCustomerMessage:(CustomerMessage*)im;
//客服->顾客
-(BOOL)sendCustomerSupportMessage:(CustomerMessage*)im;
-(BOOL)sendRTMessage:(RTMessage*)msg; -(void)enterRoom:(int64_t)roomID;
-(void)leaveRoom:(int64_t)roomID; //正在输入
-(void)sendInputing:(MessageInputing*)inputing;
//更新未读的消息数目
-(void)sendUnreadCount:(int)unread; -(void)addPeerMessageObserver:(id<PeerMessageObserver>)ob;
-(void)removePeerMessageObserver:(id<PeerMessageObserver>)ob; -(void)addGroupMessageObserver:(id<GroupMessageObserver>)ob;
-(void)removeGroupMessageObserver:(id<GroupMessageObserver>)ob; -(void)addLoginPointObserver:(id<LoginPointObserver>)ob;
-(void)removeLoginPointObserver:(id<LoginPointObserver>)ob; -(void)addRoomMessageObserver:(id<RoomMessageObserver>)ob;
-(void)removeRoomMessageObserver:(id<RoomMessageObserver>)ob; -(void)addSystemMessageObserver:(id<SystemMessageObserver>)ob;
-(void)removeSystemMessageObserver:(id<SystemMessageObserver>)ob; -(void)addCustomerMessageObserver:(id<CustomerMessageObserver>)ob;
-(void)removeCustomerMessageObserver:(id<CustomerMessageObserver>)ob; -(void)addRTMessageObserver:(id<RTMessageObserver>)ob;
-(void)removeRTMessageObserver:(id<RTMessageObserver>)ob; -(void)pushVOIPObserver:(id<VOIPObserver>)ob;
-(void)popVOIPObserver:(id<VOIPObserver>)ob; -(BOOL)sendVOIPControl:(VOIPControl*)ctl; @end
坑下挖好,慢慢补充,完整的代码和DEMO可以到[Gobelieve IM]查看。
[1]: http://developer.gobelieve.io/
商业化IM 客户端接口设计分析的更多相关文章
- cxf的使用及安全校验-02创建简单的客户端接口
上一篇文章中,我们已经讲了如果简单的创建一个webservice接口 http://www.cnblogs.com/snowstar123/p/3395568.html 现在我们创建一个简单客户端接口 ...
- Warensoft Stock Service Api客户端接口说明
Warensoft Stock Service Api客户端接口说明 Warensoft Stock Service Api Client Reference 可使用环境(Available Envi ...
- HBase新的客户端接口
最近学习接触HBase的东西,看了<Habase in Action>,但里面关于HBase接口都是过时的接口,以下为HBase新的客户端接口: package com.n10k; imp ...
- 客户端接口AGENDA
日程 周二上午:完善客户端功能.接口定义. 周二下午:助教审查客户端代码.审查完成之后将发布接口定义. 提示 总之谢谢大家的支持.我们会尽量降低交互难度,让各位亲把精力专注于算法设计上面. 可以使用任 ...
- webService 客户端接口调用【java】
最近实际项目中使用到了WebService,简单总结下使用方式: 1.拿到接口:http://*******:8080/osms/services/OrderWebService?wsdl 我们可以将 ...
- Android Asynchronous Http Client-Android异步网络请求客户端接口
1.简介 Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnect,但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求,而使用and ...
- RabbitMQ-C 客户端接口使用说明
rabbitmq-c是一个用于C语言的,与AMQP server进行交互的client库.AMQP协议为版本0-9-1.rabbitmq-c与server进行交互前需要首先进行login操作,在操作后 ...
- 关于客户端接口分页sql语句
今天突然翻到为客户端写分页数据的sql,发现其实逻辑不对.列表是按照id降序的 当时这样写的: #翻上一页: select 字段 from 表 where id>lastId order by ...
- 新浪微博Python3客户端接口OAuth2
Keyword: Python3 Oauth2 新浪微博 本接口基于廖雪峰的weibo python SDK修改完成,其sdk为新浪官方所推荐,原作者是用python2写的 经过一些修改,这里提供基于 ...
随机推荐
- jQuery Text-to-Speech 谷歌在线语音
<!DOCTYPE html> <html> <head> <meta content="text/html; charset=utf-8" ...
- thinkphp5设置404页面不跳转
thinkphp5设置404页面的步骤: 1. 首先关闭调试模式,即配置application/config文件,使'app_debug' => false 2. 添加自定义404页面跳转地址, ...
- “没有用var声明的为全局变量”这种说法不准确
结论: “没有用var声明的变量为全局变量”这样的说法不太正确,需要在这句话前面加一个前提,如果①变量前面没有用var声明,②在变量所在在的作用域链中没有这个变量名称,则设置该变量为全局变量. 代码 ...
- iframe 子页面改变父页面样式
iframe 子窗口调节父窗口样式: $(window.parent.document).find("body").attr("style"," 父元 ...
- 在IIS中浏览网站时出现:无法打开登录所请求的数据库 "***",登录失败
在IIS中发布Web应用程序后,浏览网站时出现无法打开登录所请求的数据库 "***",登录失败错误,如下图所示: 解决办法:打开系统Web.Config配置文件,查看数据库连接串是 ...
- XPath路径表达式笔记(转载)
简单说,xpath就是选择XML文件中节点的方法. 所谓节点(node),就是XML文件的最小构成单位,一共分成7种. - element(元素节点)- attribute(属性节点)- text ( ...
- apk下载安装,存储的位置,路径
PackageInstaller 原理简述 应用安装是智能机的主要特点,即用户可以把各种应用(如游戏等)安装到手机上,并可以对其进行卸载等管理操作.APK是Android Package的缩写,即An ...
- C# Winform窗体和控件自适应大小
1.在项目中创建类AutoSizeForm AutoSizeForm.cs文件代码: using System; using System.Collections.Generic; using Sys ...
- Android Button事件处理
一般只需要处理按钮的点击事件就可以,但想让一个按钮处理多个事件,就得同时监听多个方法. OnClickListener 点击事件 OnLongClickListener 长按事件 OnTouchLi ...
- Git学习-Git时光机之版本回退(二)
Git,是Linus花了两周时间用C写的一个分布式版本控制系统.牛人该怎么定义? 零.结论先行 倒叙总结一下: HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git ...