2012-11-10 31 views
0

我正在使用CocoaAsyncSocket,我需要做一个函数向服务器发送消息,并等待服务器回复,在委托方法中它接收服务器响应,但我需要发送消息的函数等待服务器回复并返回响应。从CocoaAsyncSocket读取数据

- (NSString *)sendMessage:(NSString *)message{ 
    NSError *err = nil; 
    if (![socket connectToHost:@"192.168.1.20" onPort:52523 error:&err]) // Asynchronous! 
    { 
     NSLog(@"Error is : %@", err); 
    } 

    [socket readDataWithTimeout:-1 tag:1]; 

    NSData* data =[message dataUsingEncoding:NSUTF8StringEncoding]; 
    [socket writeData:data withTimeout:-1 tag:1]; 

    NSString *xmlString = [[NSString alloc] init]; 
    // Here I need the function wait and receive the response 

    return xmlString; 
} 

回答

1

如果您需要同步发送的东西,为什么不建立一个请求,并使用NSURLConnection的API喜欢这里:

NSData* data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error]; 

这将阻止,直到你得到回应。

如果你想使用异步套接字方法来保持,但强行使其同步调用,您可以通过添加以下方法做到这一点:

@property (nonatomic, assign) BOOL com_private_condition; 
@property (nonatomic, assign) NSThread* com_private_theWaitingThread; 

...

@synthesize com_private_condition; 
@synthesize com_private_theWaitingThread; 

.. 。

- (BOOL)waitForConditionWithTimeout:(NSTimeInterval)aTimeout 
    { 
     self.com_private_condition = NO; 
     self.com_private_theWaitingThread = [NSThread currentThread]; 
     NSDate* theStartDate = [NSDate date]; 
     NSDate* theEndDate = [NSDate dateWithTimeIntervalSinceNow:aTimeout]; 
     do 
     { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
           beforeDate:theEndDate]; 
     NSTimeInterval theElapsedTime = -[theStartDate timeIntervalSinceNow]; 
     if (theElapsedTime >= aTimeout) 
     { 
      return NO; 
     } 
     if (self.com_private_condition) 
     { 
      return YES; 
     } 
    } while (YES); 
} 

- (void)signalCondition 
{ 
    [self performSelector:@selector(com_private_signalCondition:) 
       onThread:self.com_private_theWaitingThread 
       withObject:nil waitUntilDone:NO]; 
} 

- (void)com_private_signalCondition:(id)aParam 
{ 
    self.com_private_condition = YES;  
} 

现在使你的方法是这样

在CocoaAsyncSocket回调插座
- (NSString *)sendMessage:(NSString *)message{ 
    NSError *err = nil; 
    if (![socket connectToHost:@"192.168.1.20" onPort:52523 error:&err]) // Asynchronous! 
    { 
     NSLog(@"Error is : %@", err); 
    } 

    [socket readDataWithTimeout:-1 tag:1]; 

    NSData* data =[message dataUsingEncoding:NSUTF8StringEncoding]; 
    [socket writeData:data withTimeout:-1 tag:1]; 

    //make xmlString a variable on your class and set it in your async socket callback when you get the data. once the wait is over just return it. 
    //NSString *xmlString = [[NSString alloc] init]; 
    // Here I need the function wait and receive the response 

    //call read and then wait 
    [socket readDataWithTimeout:-1 tag:1]; 
    [self waitForConditionWithTimeout:9999.0]; //or some other wait timeout of your choosing 
    //this will block until [self signalCondition] is called by your socket callbacks. 

    return self.xmlString; 
} 

现在:didReadData:withTag:插座:didDisconnectWithError:确保你叫

[self signalCondition]; 

一旦你调用该方法等待将继续,并且您刚刚做出异步调用同步。

+0

我真的很欣赏您简单回答的方式,您提供的解决方案非常实用,我通过套接字来完成此任务,因为套接字在时间上更高效,我的项目需要时间效率。谢谢 –