【问题标题】:Reading data from CocoaAsyncSocket从 CocoaAsyncSocket 读取数据
【发布时间】:2012-11-10 15:12:26
【问题描述】:

我正在使用 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;
}

【问题讨论】:

    标签: iphone objective-c ios cocoaasyncsocket


    【解决方案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;    
    }
    

    现在让你的方法像这样

    - (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;
    }
    

    现在在你的 CocoaAsyncSocket 回调 socket:didReadData:withTag: 和 socket:didDisconnectWithError: 中确保你调用了

    [self signalCondition];
    

    一旦你调用了等待方法,等待方法就会继续,而你只是使异步调用同步。

    【讨论】:

    • 非常感谢您简短回答的方式,您提供的解决方案确实可行,我正在通过套接字进行此操作,因为套接字在时间上效率更高,我的项目需要时间效率。谢谢
    猜你喜欢
    • 2011-10-10
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 2021-09-20
    • 2018-04-11
    • 2012-04-03
    相关资源
    最近更新 更多