- 使用AsyncSocket的時(shí)候可以做一層封裝,根據(jù)需求提供幾個(gè)接口出來(lái)。比如:連接、斷開(kāi)連接、發(fā)送消息等等。還有接受消息,接受到的消息可以通過(guò)通知、代理、block等傳出去。
- 對(duì)AsyncSocket使用.一般來(lái)說(shuō),一個(gè)用戶(hù)只需要建立一個(gè)socket長(zhǎng)連接,所以可以用單例類(lèi)方便使用。
使用AsyncSocket
1.創(chuàng)建socket的單例類(lèi)
//在LGSocketServe.h
#import <Foundation/Foundation.h>
#import "AsyncSocket.h"
#import "GCDAsyncSocket.h"
@interface LGSocketServe : NSObject
//創(chuàng)建屬性 用于連接
@property (nonatomic, strong, readonly) GCDAsyncSocket *socket;
@property (nonatomic, copy, readonly) NSString *socketHost;
@property (nonatomic, assign, readonly) uint16_t socketPort;
//創(chuàng)建單列類(lèi)
+(instancetype)shareSocket;
@end
//在LGSocketServe.m
#import "LGSocketServe.h"
#import <UIKit/UIKit.h>
@interface LGSocketServe ()
@property (nonatomic, strong, readwrite) GCDAsyncSocket *socket;
@property (nonatomic, copy, readwrite) NSString *socketHost;
@property (nonatomic, assign, readwrite) uint16_t socketPort;
@end
@implementation LGSocketServe
+(instancetype)shareSocket
{
static dispatch_once_t onceToken;
static LGSocketServe *socket;
dispatch_once(&onceToken, ^{
socket = [[LGSocketServe alloc]init];
});
return socket;
}
- (instancetype)init
{
self = [super init];
if (self) {
self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
return self;
}
//創(chuàng)建連接
- (void)connected:(NSString *)host onPort:(uint16_t)port error:(NSError *)error{
self.socketHost = host;
self.socketPort = port;
//必須確認(rèn)在斷開(kāi)連接的情況下,進(jìn)行連接
if (self.socket.isDisconnected) {
[self.socket connectToHost:self.socketHost onPort:self.socketPort error:nil];
}else{
[self.socket disconnect];
[self.socket connectToHost:self.socketHost onPort:self.socketPort error:nil];
}
[self.socket connectToHost:host onPort:port error:nil];
}
//心跳連接
-(void)longConnectToSocket{
// 根據(jù)服務(wù)器要求發(fā)送固定格式的數(shù)據(jù),假設(shè)為指令@"longConnect",但是一般不會(huì)是這么簡(jiǎn)單的指令
NSString *longConnect = @"longConnect\r\n";
NSData *dataStream = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:dataStream withTimeout:-1 tag:0];
}
//連接成功
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
//每隔特定時(shí)間向服務(wù)器發(fā)送心跳包
//在longConnectToSocket方法中進(jìn)行長(zhǎng)連接需要向服務(wù)器發(fā)送特定信息
self.longConnectTimer
= [NSTimer timerWithTimeInterval:kSocketConnectTimerTimeInterval
target:self
selector:@selector(longConnectToSocket)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.longConnectTimer
forMode:NSRunLoopCommonModes];
}
//斷開(kāi)連接
- (void)disConnected{
[self.socket disconnect];
}
//斷開(kāi)之后重新連接
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
//這里可以列舉枚舉值
//因用戶(hù)自動(dòng)斷開(kāi) 不自動(dòng)連接
if (self.offlineError == SZYSocketOfflineByServer) {
[self.longConnectTimer invalidate];
self.longConnectTimer = nil;
[self.socket setDelegate:nil];
[self.socket disconnect];
//因服務(wù)器原因斷開(kāi) 自動(dòng)連接
}else if (self.offlineError == SZYSocketOfflineByServer){
[self.longConnectTimer invalidate];
self.longConnectTimer = nil;
[self.socket setDelegate:nil];
[self.socket disconnect];
[self.socket setDelegate:self];
[self.socket connectToHost:self.socketHost
onPort:self.socketPort
error:nil];
//因Wifi原因斷開(kāi) 不自動(dòng)連接
}else{
[self.longConnectTimer invalidate];
self.longConnectTimer = nil;
[self.socket setDelegate:nil];
[self.socket disconnect];
}
}
//寫(xiě)入數(shù)據(jù)
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag{
[self.socket writeData:data withTimeout:-1 tag:100];
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"讀取到的消息:%@", dataString);
}
//讀取數(shù)據(jù)
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag{
[self.socket readDataToData:data withTimeout:-1 tag:100];
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
NSLog(@"didWriteDataWithTag");
}