最近在review并refactor项目组其他同事的代码,其中涉及到一个知识点:GCDAsyncSocket,socket异步通信,这是一个第三发开源框架,已经被用的比较成熟了,如下是git仓库地址:https://github.com/robbiehanson/CocoaAsyncSocket.git,有兴趣的可以查看源码,如果懒一点可以直接pod 'CocoaAsyncSocket' 到本地进行使用
需求、
我们做的是人脸识别门禁考勤系统,所以需要与闸机进行通信;
实现思路:
门禁属于一开一关,以此视为一个生命周期,故采取socket短连接通信方式,用完之后client端主动关闭socket连接,下次刷脸再次创建,重复这个过程;
为什么不采用长连接?
长连接需要保持心跳,过程繁杂,不够干净利索。而且占用资源,容易消耗电能,不可取;
上代码:
//
-(void)setupSocket
{
if (_socket) {
[_socket setDelegate:nil];
_socket = nil;
}
_bReadFlag = NO;
_socket = [[AsyncSocket alloc] initWithDelegate:self];
NSLog(@"门禁IP:%@",[DefaultInfo shareUserInfo].strDoorSocket);
NSString *strDoorIP = [[[DefaultInfo shareUserInfo].strDoorSocket componentsSeparatedByString:@":"]firstObject];
int iDoorPort = [[[[DefaultInfo shareUserInfo].strDoorSocket componentsSeparatedByString:@":"]lastObject] intValue];
NSError *error = NULL;
BOOL bRet = [_socket connectToHost:strDoorIP
onPort:iDoorPort
error:&error];
if (bRet){
NSLog(@"门禁连接成功");
}else{
NSLog(@"门禁连接失败:%@",error);
[_socket setDelegate:nil];
_socket = nil;
}
}
//代理方法
-(void)onSocketDidDisconnect:(AsyncSocket *)sock {
NSLog(@"门禁DidDisconnected.");
[_socket setDelegate:nil];
_socket = nil;
}
- (BOOL)onSocketWillConnect:(AsyncSocket *)sock {
NSLog(@"门禁onSocketWillConnect:");
return YES;
}
//询问闸机server是否允许访问
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(@"门禁Connected To %@:%i.", host, port);
[self sendHTTPRequestWith:@"AT\r\n"];
[self listenData];
}
//允许访问,发送开门指令
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSString *strReceived = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
if ([strReceived containsString:@"OK"] && !_bReadFlag) {
_bReadFlag = YES;
[self sendHTTPRequestWith:@"AT+STACH0=1,3\r\n"];
[self listenData];
}else {
//打开门之后生命周期结束,断开连接
[_socket disconnect];
}
}