GCDAsyncSocket Client не читает до записи
Не так много кода для включения, но почему клиент GCDAsyncSocket может останавливать чтение до тех пор, пока writeData не будет поставлена в очередь? Симптомы:
- "didConnectToHost" не вызывается, хотя сервер вызывает "didAcceptNewSocket".
- "didReadData" не вызывается, когда сервер записывает данные
- "socketDidDisconnect" не вызывается
- сообщения от клиента передаются должным образом
Невероятно странно, но вызов метода "writeDelayed" (который просто ставит в очередь метод "writeData") позволяет правильно обрабатывать все чтения. Удаление "writeData" из метода отключает чтение.
Это заставило меня думать, что настроенная очередь отправки GCD была неправильной, поэтому я попробовал каждую новую и стандартную последовательную и параллельную очередь, возможную
Или что объект сокета был освобожден раньше времени, поэтому я сделал это свойство класса, но безрезультатно.
Одна вещь, которая может усложнять ситуацию (хотя я не знаю как), это то, что соединение устанавливается в ответ на разрешенный объект NSNetService (Bonjour), который может находиться в другой очереди отправки. Но я попытался обернуть "setupConnection" в блок для выполнения в главной очереди, но безрезультатно.
Вот небольшой объем кода, я буду редактировать, если есть какие-либо вопросы.
Спасибо Джеймс
-(void)setupConnection
{
self.queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:self.queue];
}
-(void)connect
{
NSError *error = nil;
if(![self.socket connectToHost:self.socketInfo.address onPort:self.socketInfo.port error:&error])
{
NSLog(@"I goofed: %@", error);
}
NSLog(@"Connecting to: %@:%i",self.socketInfo.address,self.socketInfo.port);
}
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
NSLog(@"Connected");
[self.socket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
}
-(void)writeDelayed
{
double delayInSeconds = 2000000.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSData* dataObj = [GCDAsyncSocket CRLFData];
[self.socket writeData:dataObj withTimeout:-1 tag:1];
});
}
...
1 ответ
Ответ заключается в том, что один из высших объектов в моей цепочке объектов был выпущен раньше, что привело к преждевременному освобождению сокета. Слово мудрым кажется.