iOS开发之AsyncSocket使用
2016-02-23 15:17
513 查看
用socket可以实现像QQ那样发送即时消息的功能。客户端和服务端需要建立长连接,在长连接的情况下,发送消息。客户端可以发送心跳包来检测长连接。
简单介绍一下对AsyncSocket使用.一般来说,一个用户只需要建立一个socket长连接,所以可以用单例类方便使用。
简单使用
参照原文链接http://www.superqq.com/blog/2015/04/03/ioskai-fa-zhi-asyncsocketshi-yong-jiao-cheng/
简单介绍一下对AsyncSocket使用.一般来说,一个用户只需要建立一个socket长连接,所以可以用单例类方便使用。
.h enum{ SocketOfflineByServer, //服务器掉线 SocketOfflineByUser, //用户断开 SocketOfflineByWifiCut, //wifi 断开 }; + (SocketServeModle *)sharedSocketServe; @property (nonatomic, strong) AsyncSocket *socket; // socket 连接 - (void)startConnectSocket; #pragma mark - heart jump @property (nonatomic, retain) NSTimer *heartTmier; // socket 断开 - (void)cutOffSocket; // 发送消息 - (void)sendMessage:(id)message;
.m #define HOST_NAME @"192.168.0.1" #define PORT 8080 // Connect time out #define TIME_OUT 20 // #define MAX_BUFFER 1024
+(SocketServeModle *)sharedSocketServe { // Create a singleton static SocketServeModle *socketServe = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ socketServe = [[SocketServeModle alloc] init]; }); return socketServe; }
#pragma mark - - (void)startConnectSocket { self.socket = [[AsyncSocket alloc] initWithDelegate:self]; [self.socket setRunLoopModes:[NSArray arrayWithObject:NSRunLoopCommonModes]]; if (![self socketOpen:HOST_NAME port:PORT]) { } }
#pragma mark - - (NSInteger)socketOpen:(NSString *)address port:(NSInteger)port { // if Connect not - fail if (![self.socket isConnected]) { NSError *error = nil; [self.socket connectToHost:address onPort:port error:&error]; } return 0; }
#pragma mark - - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { // it is asyn NSLog(@"didConnectToHost"); // 通过定时器不断的发送消息, 来检测长连接 By the timer sends a message to detect long connection self.heartTmier = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(checkLongConnectByServe) userInfo:nil repeats:YES]; [self.heartTmier fire]; }
#pragma mark - checkLongConnectByServe - (void)checkLongConnectByServe { // 向服务器发送固定的消息, 来检测长连接 NSString *longConnect = @"connect is success"; NSData *data = [longConnect dataUsingEncoding:NSUTF8StringEncoding]; [self.socket writeData:data withTimeout:1 tag:1]; }
#pragma mark - 断开 - (void)cutOffSocket { self.socket.userData = SocketOfflineByUser; [self.socket disconnect]; }
#pragma mark - 出错处理 - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err { if (err.code == 57) { self.socket.userData = SocketOfflineByWifiCut; } NSData *unreadData = [sock unreadData]; if (unreadData.length > 0) { [self onSocket:sock didReadData:unreadData withTag:0]; }else{ self.socket.userData = SocketOfflineByWifiCut; } }
#pragma mark - 回调 - (void)onSocketDidDisconnect:(AsyncSocket *)sock { if (sock.userData == SocketOfflineByServer) { // 服务器掉线, 重连 [self startConnectSocket]; }else if (sock.userData == SocketOfflineByUser){ // 如果由用户断开, 不进行重连 return; }else if (sock.userData == SocketOfflineByWifiCut){ // wifi断开 return; } }
#pragma mark - - (void)sendMessage:(id)message { // 向服务器发送数据 NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding]; // -1 表示不会使用超时 [self.socket writeData:data withTimeout:-1 tag:1]; }
#pragma mark - - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag { // 消息成功的回调 // 读取消息 [self.socket readDataWithTimeout:-1 buffer:nil bufferOffset:MAX_BUFFER tag:0]; }
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { // 服务器返回的消息数据量比较大时, 可以分多次返回, 所以在读取消息的时候,设置MAX_BUFFER表示每次最多读取多少,当data.length < MAX_BUFFER我们认为有可能是接受完一个完整的消息,然后才解析 if (data.length < MAX_BUFFER) { // 结果的解析 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSLog(@"%@", dic); // 解析出来的消息, 可以通过通知, 代理, block传出去 } [self.socket readDataWithTimeout:-1 buffer:nil bufferOffset:MAX_BUFFER tag:0]; }
简单使用
SocketServeModle *serve = [SocketServeModle sharedSocketServe]; // 连接之前先断开 [serve cutOffSocket]; serve.socket.userData = SocketOfflineByServer; [serve startConnectSocket];
参照原文链接http://www.superqq.com/blog/2015/04/03/ioskai-fa-zhi-asyncsocketshi-yong-jiao-cheng/
相关文章推荐
- iOS开发中文件的上传和下载功能的基本实现
- IOS开发证书显示“此证书的签发者无效”解决方法
- ios中修改TextField的placeholder的字体颜色和大小
- 关于IOS中的多线程(GCD)
- iOS中3种正则表达式的使用与比较
- IOS BLE4.0 数据重发的问题
- iOS App集成Apple Pay教程(附示例代码)
- 深入浅出iOS事件机制
- 使用AFNetworking请求数据成功后走了两遍success的原因
- iOS runloop
- iOS 7的手势滑动返回功能
- iOS textview滚动到底部
- iOS 下APNS推送处理函数详解
- iOS9 TableView和ScrollView滚动不响应问题
- IOS 初次接触
- iOS9适配
- iOS自定义navigationBar 的rightBarButtonItems
- iOS系统异步请求封装
- iOS小明开发笔记(十五) (Quartz2D矩阵操作)
- iOS小明开发笔记(十三) (Quartz2D简单使用二)