最近項(xiàng)目中用到了即時(shí)通訊,之前用到是騰訊的即時(shí)通訊SDK,但是這次技術(shù)老大想讓我們自己用
socket實(shí)現(xiàn),于是就研究了下CocoaAsyncSocket,目前已經(jīng)在項(xiàng)目中實(shí)現(xiàn)了即時(shí)通訊功能,特此在這里記錄一下。
開(kāi)始正文之前先說(shuō)下CocoaAsyncSocket的文件組成。
GCDAsyncSocket是用GCD搭建的基于TCP/IP協(xié)議的socket網(wǎng)絡(luò)庫(kù)。
GCDAsyncUdpSocket是用GCD搭建的基于UDP/IP協(xié)議的socket網(wǎng)絡(luò)庫(kù)。
1.導(dǎo)入pod庫(kù)
pod 'CocoaAsyncSocket','7.6.0'
2.引入頭文件,并設(shè)置代理
#import <GCDAsyncSocket.h>
<GCDAsyncSocketDelegate>
3.初始化socket對(duì)象,代理隊(duì)列必須為主隊(duì)列,同時(shí)創(chuàng)建定時(shí)器,保持心跳
@property(nonatomic,strong)GCDAsyncSocket *clientSocket;
@property (nonatomic, strong) NSTimer *connectTimer;
self.clientSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
//設(shè)置主機(jī)ip和端口號(hào)
[self.clientSocket connectToHost:@"主機(jī)ip" onPort:8080 error:nil];
//加心跳
[netWork addTimer];
// 添加定時(shí)器
- (void)addTimer{
// 長(zhǎng)連接定時(shí)器
self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];
// 把定時(shí)器添加到當(dāng)前運(yùn)行循環(huán),并且調(diào)為通用模式
[[NSRunLoop currentRunLoop] addTimer:self.connectTimer forMode:NSRunLoopCommonModes];
}
4.實(shí)現(xiàn)代理方法
#pragma mark - 成功連接服務(wù)器
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
NSLog(@"成功連接服務(wù)器");
//第一次連接服務(wù)器,發(fā)送個(gè)人信息,代表登錄
[self loginService];
}
#pragma mark - 讀取數(shù)據(jù)回調(diào)
- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag{
}
#pragma mark - 斷開(kāi)連接服務(wù)器
- (void)socketDidDisconnect:(GCDAsyncSocket*)sock withError:(NSError*)err{
//斷開(kāi)重連
[self.clientSocket connectToHost:@"主機(jī)ip" onPort:8080 error:nil];
NSLog(@"斷開(kāi)連接服務(wù)器,重新連接");
}
這里需要注意。如果斷開(kāi)服務(wù)器不需要重新連接,那么不需要調(diào)用connectToHost方法,并且需要清空代理和客戶(hù)端本身的socket.
self.clientSocket.delegate = nil;
self.clientSocket = nil;
5.建立心跳連接
- (void)longConnectToSocket{
[self loginService];
}
6.調(diào)用發(fā)送方法
//發(fā)送
[self.clientSocket writeData:data withTimeout:-1 tag:0];
這里需要注意
心跳連接中發(fā)送給服務(wù)端的數(shù)據(jù)是驗(yàn)證用戶(hù)身份的代碼,可以根據(jù)公司需求,或者和后臺(tái)商定好心跳包的數(shù)據(jù)以及發(fā)送心跳的時(shí)間間隔.客戶(hù)端發(fā)送心跳包,服務(wù)端也需要有對(duì)應(yīng)的心跳檢測(cè),以此檢測(cè)客戶(hù)端是否在線.
這里還可以用GCDAsyncSocketDelegate模擬服務(wù)端功能,但是因?yàn)楣疽呀?jīng)有后臺(tái)同事用socket實(shí)現(xiàn)功能了, 這里我就沒(méi)有進(jìn)行模擬。