AsyncSocket使用心得和一些需要注意的地方
来源:互联网 发布:云计算峰会的会议主题 编辑:程序博客网 时间:2024/05/22 07:42
首先 下载源代码
倒入runloop文件夹下的 四个文件即可
AsyncSocket *socket=[[AsyncSocketalloc]initWithDelegate:self];
NSError *error;
[socket connectToHost:h onPort:p withTimeout:-1error:&error ];
然后实现一些Delegate方法
A:- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
B:- (void)onSocketDidSecure:(AsyncSocket *)sock;
C:- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
D:- (void)onSocketDidDisconnect:(AsyncSocket *)sock;
E:- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
监听网络操作
如果链接成功会调用A
如果我们想读取数据 就在A方法中 加入[socket readDataWithTimeout:-1 tag:0]; 当收到数据的时候 会调用E 当调用E之后 我们的这个读取请求就完成了
不再监听网络, 若想一直监听网络 在E中 也加入[socket readDataWithTimeout:-1 tag:0];
这个库若想监听网络,必须先设置[socket readDataWithTimeout:-1 tag:0];这里面的tag很重要。如果你写的时候用的tag与读的不相同,那么永远在回调的地方没有回复。
当读的时候,需要判断长度是否足够,如果不够需要再次设置[socket readDataWithTimeout:-1 tag:0];
如果你需要保持这条链路,就不要用它的超时,因为默认超时,会断开连接。你再超时回调处,再次设置时间,也只是延长等待时间,到点仍是断链。
cilent向主机发送命令,每次发送一条后 主动断开
connectToHost:这个方法会返回一个bool 但是每次都返回yes 原因是这个方法yes 与no 表示 是否尝试着去链接host 并不代表是否链接成功
所以要想知道是否链接成功 要看是否调用了A方法
如果我们写如下的代码
-(void)xxxxxxxxpressed:(xxx)xxxx{
[socket connectToHost:h onPort:p withTimeout:-1error:&error ];
[socket writeData:currentConmandwithTimeout:-1tag:button.tag];
[socket disconnectAfterWriting];
}
每次事件发生的时候 进行链接 并且马上发送数据,然后 等Writing结束后 撤销链接 这样在100%能链接上的情况下是没有问题的
但是 当主机出现问题 链接不上的时候, connectToHost:之后 马上写入数据,但是这个写入请求永远不会完成,所以之后的disconnectAfterWriting
一直会等待下去不执行,则这个connect仍然处于链接失败 状态。
当下一次事件发生的时候,会再次链接,这时程序崩溃,错误信息是告诉我们 必须先disconnect之后 才能再次链接
原因是 connect失败导致写入无法完成,所以disconnectAfterWriting 也就无法完成
解决办法 在 这个方法的最开始 加入几句代码
[socketsetDelegate:nil];
[socket disconnect];
socket=nil;
然后每次都重新初始化一次socket即可
项目实战 二维码监听 付款成功:
import "AsyncSocket.h"
@interface YFScannerViewController ()<AsyncSocketDelegate> {
UIBarButtonItem *_rightItem;
CGFloat _brightness;
UIImageView *_imageView;
NSTimer *_timer;
NSInteger totalTime;
AsyncSocket *_socket;
}
- (void)startSocket;
- (void)heartBeat;
- (void)getCode;
@end
@implementation YFScannerViewController
- (void)viewWillAppear:(BOOL)animated
{
[[UIApplicationsharedApplication]setIdleTimerDisabled:YES];
_brightness = [UIScreenmainScreen].brightness;
[[UIScreenmainScreen]setBrightness:1.0f];
// [_timer setFireDate:[NSDate distantPast]];
[selfstartSocket];
// [self getCode];
}
#pragma mark - Socket
//创建 socket连接
- (void)startSocket
{
DLog(@"_socket.userData%ld",_socket.userData);
if (!_socket)
_socket = [[AsyncSocketalloc]initWithDelegate:self];
[_socketconnectToHost:@"111.198.74.31"onPort:51066withTimeout:60error:nil];
[_socketreadDataWithTimeout:-1tag:1000];
}
//读取连接成功之后的数据
- (void)heartBeat
{
NSString *message = [NSStringstringWithFormat:@"0A10013D%@", [USER_DEFAULTobjectForKey:kUserId]];
[_socketwriteData:[messagedataUsingEncoding:NSUTF8StringEncoding]withTimeout:60tag:2000];
[selfperformSelector:@selector(heartBeat)withObject:nilafterDelay:30.0];
}
//断开 socket连接
- (void)socketDisconnect
{
_socket.userData =SocketUsetData_Exit;
[_socketdisconnect];
_socket=nil;
}
//链接成功
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSString *message = [NSStringstringWithFormat:@"0A10013E%@", [USER_DEFAULTobjectForKey:kUserId]];
//读取数据
[_socketwriteData:[messagedataUsingEncoding:NSUTF8StringEncoding]withTimeout:60tag:2000];
[selfperformSelector:@selector(heartBeat)withObject:nilafterDelay:30.0];
}
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
[NSObjectcancelPreviousPerformRequestsWithTarget:selfselector:@selector(getCode)object:nil];
[NSObjectcancelPreviousPerformRequestsWithTarget:selfselector:@selector(heartBeat)object:nil];
[NSObjectcancelPreviousPerformRequestsWithTarget:selfselector:@selector(startSocket)object:nil];
if (_socket.userData ==SocketUsetData_Exit)
return;
[selfperformSelector:@selector(startSocket)withObject:nilafterDelay:5.0];
}
//收到数据的时候调用
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
NSString *key =@"123456781234567812345678";
NSString *str = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
str = [str stringByReplacingOccurrencesOfString:@"\n"withString:@""];
str = [str stringByReplacingOccurrencesOfString:@"\r"withString:@""];
NSArray *array = [strcomponentsSeparatedByString:@"|"];
//此时其实网络监听已经完成了 若想继续监听 这个tag必须和之前的是一致的
[_socketreadDataWithTimeout:-1tag:1000];
if([arraycount] !=4)return ;
NSString *receipt = [NSStringstringWithFormat:@"0A10102D%@", [arrayfirstObject]];
[_socketwriteData:[receiptdataUsingEncoding:NSUTF8StringEncoding]withTimeout:60tag:2000];
//解密
NSMutableDictionary *dic = [[NSMutableDictionaryalloc]init];
if ([[arrayobjectAtIndex:1]intValue] == 1)
{
YF_Pay_KaTool *tool = [[YF_Pay_KaToolalloc]init];
NSData *_data = [[arrayobjectAtIndex:2]dataUsingEncoding:NSUTF8StringEncoding];
_data = [tool.base64decode:_data];
_data = [tool._3Desdecode:_datakey:key];
dic = [NSJSONSerializationJSONObjectWithData:_dataoptions:0error:nil];
}
/*断开连接*/
[selfperformSelector:@selector(socketDisconnect)withObject:nilafterDelay:2.0];
YFPaySuccessViewController *vc =StoryboardName(@"YFPaySuccessViewController");
YFPaySuccessModel *model = [[YFPaySuccessModelalloc]init];
model.type =PayType_ToCode;
model.bankBillNo = dic[@"orderNo"];
model.bankAcctDate = dic[@"createTime"];
model.bankReceiptNo = dic[@"cardNo"];
model.payAmount = dic[@"orderPrice"];
vc.model = model;
[self.navigationControllerpushViewController:vcanimated:YES];
}
//离开界面的时候 去掉_socket连接
- (void)backBtnPressed
{
[selfsocketDisconnect];
[self.navigationControllerpopViewControllerAnimated:YES];
}
- AsyncSocket使用心得和一些需要注意的地方
- 一些需要注意的地方
- ckeditor插件的使用方法和一些需要注意的地方。
- spring3和spring4的一些需要注意的地方
- (转载)spring3和spring4的一些需要注意的地方
- 使用指针赋值一些需要注意的地方
- 对于system用户使用一些api需要注意的地方
- Mysql分区表使用的一些限制和需要注意的地方
- Mysql分区表使用的一些限制和需要注意的地方
- Mysql分区表使用的一些限制和需要注意的地方
- nginx配置ws和一些配置需要注意的地方
- 一些常需要注意的地方
- Java中的一些需要注意的地方
- JS一些需要注意的地方
- Rose框架一些需要注意的地方
- 配库时需要注意的一些地方
- java HashMap需要注意的一些地方
- nasm汇编一些需要注意的地方
- React+Redux架构的CMSweb后台管理系统
- Redis常用命令
- html表单总结小笔记
- javaScript与app交互
- 小知识点
- AsyncSocket使用心得和一些需要注意的地方
- Redis实战:如何构建类微博的亿级社交平台
- yarn编码获取application列表
- Android_OutOfMemoryError
- 练习4-13 编写一个递归版本的reverse(s)函数,以将字符串s倒置
- yii2.0自定义rule来验证多个属性
- 常用加密算法上
- 源值1.5已过时,将在未来所有版本中删除
- 单行函数(转换函数,特有的函数)