iOS - 基于CocoaAsyncSocket搭建完整的IM体系大体思路详解

demo下载地址 : https://github.com/coderMyy/CocoaAsyncSocket_Demo , 如果觉得有那么一丁点用 , 麻烦点一颗star ,谢谢.

想要搭建一个完善 ,且自定义程度较高 , 又便于后期维修和修改的IM体系 , 采用环信或者融云等实际上是非常消耗精力和时间的 ,因为他们做得也不完善 . 目前咱们已知的通信协议大概有MQTT , XMPP等 .. 然而 , 通信协议是别人制定好的规则 , 想要不受约束 , 就需要自定义一套属于自己的通信协议 . 其实通信协议并不难 , 无非就是iOS端,安卓端,web端和服务器共同协商一套,大家的交流方式 . 话不多说 , 目前项目中功能除了视频通话和语音通话 ,其他IM的功能基本上已经实现, 跟微信对比 . 当然还有很多的细节需要改进和完善 . iOS客户端的TCP是基于CocoaAsyncSocket开源框架 , 服务器采用Netty框架 , 安卓采用Netty框架.

Appdelegate
#import "AppDelegate.h"
#import "RealReachability.h"


@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //开启网络监听
    [GLobalRealReachability startNotifier];

    return YES;
}
@end

登录用户信息单例
#import <Foundation/Foundation.h>

@interface Account : NSObject<NSCoding>

@property (nonatomic ,copy) NSString *myUserID; //当前用户ID

@property (nonatomic ,strong) NSNumber *sex; //性别

@property (nonatomic ,strong) NSNumber *age; //年龄

@property (nonatomic ,copy) NSString *birthDay; //生日

@property (nonatomic ,strong,getter=isVip) NSNumber *vip; //是否会员

@property (nonatomic ,strong,getter=isOnline) NSNumber *online;//是否在线

@property (nonatomic ,copy) NSString *lastLoginTime; //最后登录时间

/*
 这里仅仅是一个模拟 , 真正的关于当前用户的资料可能还会有很多
 */

+ (instancetype)shareInstance;

@end
.m文件
#import "Account.h"

@implementation Account

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}

//单例
+ (instancetype)shareInstance
{
    static Account *account = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        account = [[Account alloc]init];
    });
    return account;
}

//runtime快速解档
- (id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super init]) {
        unsigned int count = 0;
        Ivar *ivar = class_copyIvarList([Account class], &count);
        for (NSInteger index = 0; index<count; index++) {
            Ivar iva = ivar[index];
            const char *name = ivar_getName(iva);
            NSString *strName = [NSString stringWithUTF8String:name];
            id value = [decoder decodeObjectForKey:strName];
            [self setValue:value forKey:strName];
        }
        free(ivar);
    }
    return self;
}

//runtime快速归档
- (void)encodeWithCoder:(NSCoder *)encoder
{
    unsigned int count;
    Ivar *ivar = class_copyIvarList([Account class], &count);
    for (NSInteger index = 0; index <count; index++) {
        Ivar iv = ivar[index];
        const char *name = ivar_getName(iv);
        NSString *strName = [NSString stringWithUTF8String:name];
        id value = [self valueForKey:strName];
        [encoder encodeObject:value forKey:strName];
    }
    free(ivar);
}

当前登录用户信息操作工具类
#import <Foundation/Foundation.h>
#import "Account.h"

@interface AccountTool : NSObject

//保存个人信息
+ (void)save:(Account *)account;

//获取个人信息
+ (Account *)account;

@end
.m 文件
#import "AccountTool.h"

@implementation AccountTool

//当存当前用户信息
+ (void)save:(Account *)account
{
    NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.arch"];
    [NSKeyedArchiver archiveRootObject:account toFile:cachePath];
}

//获取当前登录用户信息
+ (Account *)account
{
    NSString *cachePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.arch"];
    return [NSKeyedUnarchiver unarchiveObjectWithFile:cachePath];
}

@end

消息模型
#import <Foundation/Foundation.h>

//TCP连接状态
typedef NS_ENUM(NSInteger) {

    SocketConnectStatus_UnConnected       = 0<<0,//未连接状态
    SocketConnectStatus_Connected         = 1<<0,//连接状态
    SocketConnectStatus_DisconnectByUser  = 2<<0,//主动断开连接
    SocketConnectStatus_Unknow            = 3<<0 //未知

}SocketConnectStatus;

//消息类型
typedef NS_ENUM(NSInteger){

    ChatMessageType_Login            = 0<<0,
    ChatMessageType_Normal           = 1<<0, //正常消息,文字,图片,语音,文件,撤回,提示语等..
    ChatMessageType_Validate         = 2<<0, //验证消息,添加好友,申请入群等..
    ChatMessageType_System           = 3<<0, //系统消息 ,xxx退出群,xxx加入群等..
    ChatMessageType_NormalReceipt    = 4<<0, //发送消息回执
    ChatMessageType_LoginReceipt     = 5<<0, //登录回执
    ChatMessageType_InvalidReceipt   = 6<<0, //消息发送失败回执
    ChatMessageType_RepealReceipt    = 7<<0, //撤回消息回执
    ChatMessageContentType_Unknow    = 8<<0   // 未知消息类型

}ChatMessageType;

//消息内容类型
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值