via:
AVOS Cloud Blog
很多开发者想在自己的 App 中添加实时通讯的功能,但通常因为没有合适的后端支持,最终没能实现。而 AVOSCloud 与时俱进,给大家带来了希望。下面就来介绍使用 AVOSCloud 给自己的 App 添加实时通讯功能。
AVOSCloud SDK 从 2.5.9 开始提供了实时通讯模块。本文主要基于 iOS SDK 2.6.2.1 实现,假设你已经具有一定的 iOS 开发基础,省略掉非实时通讯相关的代码,
github 完整代码点此 。
概念
- peerId
唯一表示一个用户的标识,可以是用户名、用户 ID 或设备 ID 等等跟用户关联的东西
- Session
表示一个会话,处理底层网络连接,收发消息
- Message
消息,可以自己定义格式,如文本或 JSON 等,从而达到实现不同类型消息的目的
- Group
群组,一个用户集合的抽象,给一个群组发送消息,群组里面所有的人都将收到此消息
实现
此部分只列出了通讯相关的代码,省略了一些本地对话和消息保存的代码。完整代码可以查看
github 完整代码
初始化
首先是 SDK 的初始化,在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 里面添加以下代码完成 SDK 的初始化
复制代码
- [AVOSCloud setApplicationId:AVOSAppID
- clientKey:AVOSAppKey];
|
然后是通讯模块的初始化,这里使用一个 CDSessionManager 的单例类来管理。这里有两部分
复制代码
- - (instancetype)init {
- if ((self = [super init])) {
- ...
-
- AVSession *session = [[AVSession alloc] init];
- session.sessionDelegate = self;
- session.signatureDelegate = self;
- _session = session;
-
- ...
- [self commonInit];
- }
- return self;
- }
|
这里是在整个运行周期只会运行一次的代码,主要是构造一个 Session。
复制代码
- - (void)commonInit {
- ...
- //打开 session
- [_session open:[AVUser currentUser].username withPeerIds:nil];
-
- ...
- while ([rs next]) { //遍历本地保存的对话记录
- ...
- if (type == CDChatRoomTypeSingle) {
- [peerIds addObject:otherid];
- } else if (type == CDChatRoomTypeGroup) {
- ...
- //加入到已保存的 group 对话中
- AVGroup *group = [_session getGroup:otherid];
- group.delegate = self;
- [group join];
- }
- ...
- }
- //加入已保存的个人对话
- [_session watchPeers:peerIds];
- initialized = YES;
- }
|
这里是每次重新登录后都会运行的代码,主要包括打开 session,恢复对话,这里使用用户名作为 peerId。
开启对话
对话就是自己与某一个对象(包括个人或群组)的通讯过程,开启一个个人对话
复制代码
- - (void)addChatWithPeerId:(NSString *)peerId {
- BOOL exist = NO;
- ...
- if (!exist) { //如果对话已经存在就跳过
- [_session watchPeers:@[peerId]];
- ...
- }
- }
|
开启一个群组对话,这里包括新建群组和加入已有群组
复制代码
- - (AVGroup *)startNewGroup { //新建群组
- AVGroup *group = [_session getGroup:nil];
- group.delegate = self;
- [group join];
- return group;
- }
|
复制代码
- - (AVGroup *)joinGroup:(NSString *)groupId { //加入已有群组
- BOOL exist = NO;
- ...
- if (!exist) { //如果对话已经存在就跳过
- AVGroup *group = [_session getGroup:groupId];
- group.delegate = self;
- [group join];
-
- ...
- }
- return [_session getGroup:groupId];
- }
|
发送消息
发送消息给个人
复制代码
- - (void)sendMessage:(NSString *)message toPeerId:(NSString *)peerId {
- ...
- [_session sendMessage:payload isTransient:NO toPeerIds:@[peerId]];
-
- ...
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_MESSAGE_UPDATED object:nil userInfo:dict];
-
- }
|
发送消息给群组
复制代码
- - (void)sendMessage:(NSString *)message toGroup:(NSString *)groupId {
- ...
- [[_session getGroup:groupId] sendMessage:payload isTransient:NO];
-
- ...
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_MESSAGE_UPDATED object:nil userInfo:dict];
-
- }
|
代码中 notification 用于通知 UI 更新
接收消息
接收个人消息
复制代码
- - (void)onSessionMessage:(AVSession *)session message:(NSString *)message peerId:(NSString *)peerId {
- ...
- BOOL exist = NO;
- ...
- if (!exist) { //还没有与该人的对话
- [self addChatWithPeerId:peerId];
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SESSION_UPDATED object:session userInfo:nil];
- }
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_MESSAGE_UPDATED object:session userInfo:dict];
-
- }
|
接收群组消息
复制代码
- - (void)session:(AVSession *)session group:(AVGroup *)group didReceiveGroupMessage:(NSString *)message fromPeerId:(NSString *)peerId {
- ...
- BOOL exist = NO;
- ...
- if (!exist) { //还没有与该群组的对话,你可能在别的客户端加入了此群组,但此客户端还没有创建对话记录
- [self joinGroup:group.groupId];
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SESSION_UPDATED object:session userInfo:nil];
- }
-
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_MESSAGE_UPDATED object:session userInfo:dict];
- }
|
接收群组事件
复制代码
- - (void)session:(AVSession *)session group:(AVGroup *)group didReceiveGroupEvent:(AVGroupEvent)event memberIds:(NSArray *)memberIds {
- ...
- if (event == AVGroupEventSelfJoined) { //接收到自己加入群组成功的事件,新加入的群组在此时才能获取 groupId
- BOOL exist = NO;
- ...
- if (!exist) {
- ...
- [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SESSION_UPDATED object:session userInfo:nil];
- }
- }
- }
|