对于刚接触IM(即时通讯)开发,通过阅读成熟的商业代码能够对即时通讯软件大体上有个认识,比如消息发送,消息接受,消息监听,群聊,单聊,聊天室。我这边直接拿[Gobelieve IM]源码来做剖析。IMService在代码层级里起着承上启下的作用,负责发送消息,接受消息(聊天消息,系统消息,控制命令消息(比如邀请VOIP,退群,加群)),消息在客户端转发,消息类型判断和分发,消息observer的增加和删除,IMService本身会根据业务需求实现handlers对接到数据传输层(socket)。Observers是衔接IMService和UI层。如果只侧重于UI层开发,重点是Observers,比如PeerMessageObserver是一对一聊天监听,GroupMessageObserver:群聊天监听,RoomMessageObserver:聊天室监听。

  1. 下面直接上接口代码来说,
  1. @class IMessage;

  IMessage 模型类的前置声明

  1. @protocol IMPeerMessageHandler <NSObject>
  2. -(BOOL)handleMessage:(IMMessage*)msg uid:(int64_t)uid;
  3. -(BOOL)handleMessageACK:(int)msgLocalID uid:(int64_t)uid;
  4. -(BOOL)handleMessageFailure:(int)msgLocalID uid:(int64_t)uid;
  5. @end

一对一聊天的hanlder定义,IM有一个ACK的设计,用来显示消息是否已经通过服务器下发到对方客户端。具体的函数,handleMessage()接收到消息的处理函数。handleMessageACK()接收到消息已读的处理函数。 handleMessageFailure()接收到消息发送失败的处理函数。

  1. @protocol IMGroupMessageHandler <NSObject>
  2.  
  3. -(BOOL)handleMessage:(IMMessage*)msg;
  4. -(BOOL)handleMessageACK:(int)msgLocalID gid:(int64_t)gid;
  5. -(BOOL)handleMessageFailure:(int)msgLocalID gid:(int64_t)gid;
  6.  
  7. -(BOOL)handleGroupNotification:(NSString*)notification;
  8. @end

群聊天的hanlder定义,接口上比单聊多一个群状态改变的处理,还有就是单聊下发的是个人ID,群聊下发的是群聊ID,同样的函数,handleMessage()接收到消息的处理函数。handleMessageACK()接收到消息已读的处理函数。 handleMessageFailure()接收到消息发送失败的处理函数。handleGroupNotification(),处理群状态改变的函数,比如群名称改变,群成员改变,群解散等等事件。

  1. @protocol IMCustomerMessageHandler <NSObject>
  2. -(BOOL)handleCustomerSupportMessage:(CustomerMessage*)msg;
  3. -(BOOL)handleMessage:(CustomerMessage*)msg;
  4. -(BOOL)handleMessageACK:(CustomerMessage*)msg;
  5. -(BOOL)handleMessageFailure:(CustomerMessage*)msg;
  6. @end

  客服聊天的handler定义。

  1. @protocol LoginPointObserver <NSObject>
  2. //用户在其他地方登陆
  3. -(void)onLoginPoint:(LoginPoint*)lp;
  4. @end

  多端登录事件监听。

  1. @protocol PeerMessageObserver <NSObject>
  2. @optional
  3. -(void)onPeerMessage:(IMMessage*)msg;
  4.  
  5. //服务器ack
  6. -(void)onPeerMessageACK:(int)msgLocalID uid:(int64_t)uid;
  7.  
  8. //消息发送失败
  9. -(void)onPeerMessageFailure:(int)msgLocalID uid:(int64_t)uid;
  10.  
  11. //对方正在输入
  12. -(void)onPeerInputing:(int64_t)uid;
  13.  
  14. @end

  一对一聊天的Observer的定义,提供了对输入状态监听的接口,用来实现,实时获取对方是否在编辑消息。

  1. @protocol GroupMessageObserver <NSObject>
  2. @optional
  3. -(void)onGroupMessage:(IMMessage*)msg;
  4. -(void)onGroupMessageACK:(int)msgLocalID gid:(int64_t)gid;
  5. -(void)onGroupMessageFailure:(int)msgLocalID gid:(int64_t)gid;
  6.  
  7. -(void)onGroupNotification:(NSString*)notification;
  8. @end

  群聊天的Observer的定义。

  1. @protocol RoomMessageObserver <NSObject>
  2. @optional
  3. -(void)onRoomMessage:(RoomMessage*)rm;
  4. -(void)onRoomMessageACK:(RoomMessage*)rm;
  5. -(void)onRoomMessageFailure:(RoomMessage*)rm;
  6.  
  7. @end

  聊天室消息Observer的定义。

  1. @protocol RTMessageObserver <NSObject>
  2.  
  3. @optional
  4. -(void)onRTMessage:(RTMessage*)rt;
  5.  
  6. @end
  7.  
  8. @protocol SystemMessageObserver <NSObject>
  9. @optional
  10. -(void)onSystemMessage:(NSString*)sm;
  11.  
  12. @end

  系统消息的Observer的定义。

  1. @protocol CustomerMessageObserver <NSObject>
  2. @optional
  3. -(void)onCustomerMessage:(CustomerMessage*)msg;
  4. -(void)onCustomerSupportMessage:(CustomerMessage*)msg;
  5.  
  6. //服务器ack
  7. -(void)onCustomerMessageACK:(CustomerMessage*)msg;
  8. //消息发送失败
  9. -(void)onCustomerMessageFailure:(CustomerMessage*)msg;
  10. @end

  客服消息的Observer的定义。

  1. @protocol VOIPObserver <NSObject>
  2.  
  3. -(void)onVOIPControl:(VOIPControl*)ctl;
  4.  
  5. @end

  支持整合VOIP功能的Observer的定义。

  1. @interface IMService : TCPConnection
  2. @property(nonatomic, copy) NSString *deviceID;
  3. @property(nonatomic, copy) NSString *token;
  4. @property(nonatomic) int64_t uid;
  5. //客服app需要设置,普通app不需要设置
  6. @property(nonatomic) int64_t appID;
  7.  
  8. @property(nonatomic, weak)id<IMPeerMessageHandler> peerMessageHandler;//一对一聊天Handler
  9. @property(nonatomic, weak)id<IMGroupMessageHandler> groupMessageHandler;//群聊handler
  10. @property(nonatomic, weak)id<IMCustomerMessageHandler> customerMessageHandler;//客服handler
  11.  
  12. 当前的IMService实现了三个(一对一聊天,群聊,客服)handler,可以按自己需要增加新的handler类型。消息统一在IMService做转发。
  13. 根据注册的Observer,传递到对该消息类型感兴趣的界面。
  14.  
  15. +(IMService*)instance;//IMService是单例的形式使用
  16.  
  17. -(BOOL)isPeerMessageSending:(int64_t)peer id:(int)msgLocalID;
  18. -(BOOL)isGroupMessageSending:(int64_t)groupID id:(int)msgLocalID;
  19. -(BOOL)isCustomerSupportMessageSending:(int)msgLocalID
  20. customerID:(int64_t)customerID
  21. customerAppID:(int64_t)customerAppID;
  22. -(BOOL)isCustomerMessageSending:(int)msgLocalID storeID:(int64_t)storeID;
  23.  
  24. -(BOOL)sendPeerMessage:(IMMessage*)msg;
  25. -(BOOL)sendGroupMessage:(IMMessage*)msg;
  26. -(BOOL)sendRoomMessage:(RoomMessage*)msg;
  27. //顾客->客服
  28. -(BOOL)sendCustomerMessage:(CustomerMessage*)im;
  29. //客服->顾客
  30. -(BOOL)sendCustomerSupportMessage:(CustomerMessage*)im;
  31. -(BOOL)sendRTMessage:(RTMessage*)msg;
  32.  
  33. -(void)enterRoom:(int64_t)roomID;
  34. -(void)leaveRoom:(int64_t)roomID;
  35.  
  36. //正在输入
  37. -(void)sendInputing:(MessageInputing*)inputing;
  38. //更新未读的消息数目
  39. -(void)sendUnreadCount:(int)unread;
  40.  
  41. -(void)addPeerMessageObserver:(id<PeerMessageObserver>)ob;
  42. -(void)removePeerMessageObserver:(id<PeerMessageObserver>)ob;
  43.  
  44. -(void)addGroupMessageObserver:(id<GroupMessageObserver>)ob;
  45. -(void)removeGroupMessageObserver:(id<GroupMessageObserver>)ob;
  46.  
  47. -(void)addLoginPointObserver:(id<LoginPointObserver>)ob;
  48. -(void)removeLoginPointObserver:(id<LoginPointObserver>)ob;
  49.  
  50. -(void)addRoomMessageObserver:(id<RoomMessageObserver>)ob;
  51. -(void)removeRoomMessageObserver:(id<RoomMessageObserver>)ob;
  52.  
  53. -(void)addSystemMessageObserver:(id<SystemMessageObserver>)ob;
  54. -(void)removeSystemMessageObserver:(id<SystemMessageObserver>)ob;
  55.  
  56. -(void)addCustomerMessageObserver:(id<CustomerMessageObserver>)ob;
  57. -(void)removeCustomerMessageObserver:(id<CustomerMessageObserver>)ob;
  58.  
  59. -(void)addRTMessageObserver:(id<RTMessageObserver>)ob;
  60. -(void)removeRTMessageObserver:(id<RTMessageObserver>)ob;
  61.  
  62. -(void)pushVOIPObserver:(id<VOIPObserver>)ob;
  63. -(void)popVOIPObserver:(id<VOIPObserver>)ob;
  64.  
  65. -(BOOL)sendVOIPControl:(VOIPControl*)ctl;
  66.  
  67. @end

  坑下挖好,慢慢补充,完整的代码和DEMO可以到[Gobelieve IM]查看。

[1]: http://developer.gobelieve.io/

商业化IM 客户端接口设计分析的更多相关文章

  1. cxf的使用及安全校验-02创建简单的客户端接口

    上一篇文章中,我们已经讲了如果简单的创建一个webservice接口 http://www.cnblogs.com/snowstar123/p/3395568.html 现在我们创建一个简单客户端接口 ...

  2. Warensoft Stock Service Api客户端接口说明

    Warensoft Stock Service Api客户端接口说明 Warensoft Stock Service Api Client Reference 可使用环境(Available Envi ...

  3. HBase新的客户端接口

    最近学习接触HBase的东西,看了<Habase in Action>,但里面关于HBase接口都是过时的接口,以下为HBase新的客户端接口: package com.n10k; imp ...

  4. 客户端接口AGENDA

    日程 周二上午:完善客户端功能.接口定义. 周二下午:助教审查客户端代码.审查完成之后将发布接口定义. 提示 总之谢谢大家的支持.我们会尽量降低交互难度,让各位亲把精力专注于算法设计上面. 可以使用任 ...

  5. webService 客户端接口调用【java】

    最近实际项目中使用到了WebService,简单总结下使用方式: 1.拿到接口:http://*******:8080/osms/services/OrderWebService?wsdl 我们可以将 ...

  6. Android Asynchronous Http Client-Android异步网络请求客户端接口

    1.简介 Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnect,但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求,而使用and ...

  7. RabbitMQ-C 客户端接口使用说明

    rabbitmq-c是一个用于C语言的,与AMQP server进行交互的client库.AMQP协议为版本0-9-1.rabbitmq-c与server进行交互前需要首先进行login操作,在操作后 ...

  8. 关于客户端接口分页sql语句

    今天突然翻到为客户端写分页数据的sql,发现其实逻辑不对.列表是按照id降序的 当时这样写的: #翻上一页: select 字段 from 表 where id>lastId order by ...

  9. 新浪微博Python3客户端接口OAuth2

    Keyword: Python3 Oauth2 新浪微博 本接口基于廖雪峰的weibo python SDK修改完成,其sdk为新浪官方所推荐,原作者是用python2写的 经过一些修改,这里提供基于 ...

随机推荐

  1. nodejs繁琐地自建路由

    一.繁琐的自建路由 app.js var server = require('./server'); server.startServer(); server.js var http = requir ...

  2. JavaScript中callee,caller,argument的理解

    argument代表当前函数的参数数组: 1.callee的用法: argument.callee表示谁引用的这个函数 其他解释:(arguments.callee表示引用当前正在执行的函数,或者说是 ...

  3. 关于移动web开发过程中的”点透“问题

    先说说故事发生的场景,举个栗子如下图: A是遮罩层,B是正常的DOM,C是B上的某个元素,这里是链接.场景是点击A的时候A消失,结果点到了C,页面发生了跳转,这显然不是咱想要的~ 下面我们来监测点击事 ...

  4. 合并excel的多个sheet

    '合并excel的多个sheetSub 合并当前工作簿下的所有工作表()Application.ScreenUpdating = FalseFor j = 1 To Sheets.Count If S ...

  5. easyui grid 本地做分页

    背景: 有的数据不是很多,但是有分页的需求,这个时候后台往往没有做分页,我们是一次请求了所有的数据. 代码: dataSource 为 grid 里的数据源 html部分: <table id= ...

  6. How to use Log4cplus

    Introduction Log4cplus is derived by the popular Log4j written in java.<br>This tutorial show ...

  7. ubuntu 18 设置语言环境

    1. 查看语言环境 ubuntu系统中,存在两个系统变量:$LANG和$LANGUAGE 分别控制语言环境和地区,这两个变量是从/etc/default/locale中读取的: 方法一: echo $ ...

  8. Ubuntu 18.04 的网络配置

    netplan简介 目前,ubuntu18.04上使用了netplan 作为网络配置工具:在终端上配置网络参数跟之前的版本有比较大的差别 Netplan工作流程如下图所示:通过读取  /etc/net ...

  9. angular2 文件上传

    ng2-file-upload文件上传 1.安装ng2-file-upload模块 npm install ng2-file-upload --save 2.如果使用systemjs打包,需要在配置s ...

  10. Oracle数据库设计实例-实时生产效率系统数据库设计

    Oracle数据库设计实例-实时生产效率系统数据库设计 引言 1.1 设计前提 某部门经理要求IT部门设计一个流水线实时生产效率系统,用来统计实时的生产量和效率.流水线有数百条,实时间隔为1min. ...