2012-07-08 38 views
11

में एक सॉकेट कनेक्शन जिंदा रखना मेरे पास उद्देश्य-सी में लिखा गया कोड है जो सॉकेट को डेटा लिखता है। सर्वर Ubuntu के शीर्ष पर Node.js चल रहा है:आईओएस

NSString *url = @"anIPAddress";   
CFReadStreamRef readStream; 
CFWriteStreamRef writeStream;    
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)url, 9000, &readStream, &writeStream); 
self.inputStream = (NSInputStream *)readStream;    
self.outputStream = (NSOutputStream *)writeStream; 
[self.inputStream setDelegate:self];    
[self.outputStream setDelegate:self];    
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];    
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];    
[self.inputStream open];    
[self.outputStream open]; 

मैं सर्वर से कनेक्ट और जानकारी भेजने के लिए कर रहा हूँ। हालांकि मैंने कुछ मिनटों के बाद कनेक्शन के समय को देखा (मुझे लगता है कि 5 मिनट या तो?)। मैं इस कनेक्शन को जिंदा कैसे रख सकता हूं? मुझे पता है कि एक डिस्कनेक्ट है क्योंकि वही बात होती है जब मैं टर्मिनल के तहत सर्वर से कनेक्ट करता हूं, मुझे उस कनेक्शन को जिंदा रखना होगा। मुझे कल्पना है कि मेरे कोड में भी यही बात हो रही है। आपकी सहायताके लिए धन्यवाद!

+0

उद्देश्य-सी कोड जो काम करता है, कृपया [निम्नलिखित उत्तर] (http://stackoverflow.com/a/25725181) देखें ... – Despotovic

उत्तर

3

मुझे पता चला कि यह कैसे करें। के बाद से सर्वर Node.js चल रहा है, मैं

socket.setKeepAlive(true, 2000); 

इस्तेमाल किया और इस तरह से नोड में प्रत्येक सॉकेट खुला रहता है। डिफ़ॉल्ट गलत है, इसलिए यही समय समाप्त हो गया था। मुझे उम्मीद है कि यह अन्य लोगों के लिए उपयोगी है। आपके जवाबों के लिए धन्यवाद, मुझे लगता है कि दिल की धड़कन रखना (जीवित रखना) भी एक अच्छा विचार है, लेकिन इस देशी दृष्टिकोण के साथ नोड इसका ख्याल रखता है।

+0

आपने आईओएस स्ट्रीम के साथ शुरुआत की और अब आप काम कर रहे हैं सॉकेट ऑब्जेक्ट के साथ जी? आप किस तरह का एपीआई का उपयोग कर रहे हैं? –

+1

@ItayLevin वह आपको दिखा रहा है कि उसने सर्वर पर यह कैसे किया - आईओएस पर इसे कैसे करें इसके लिए नीचे दिए गए जवाब देखें। –

6

सबसे आसान जवाब SO_KEEPALIVE सॉकेट विकल्प का उपयोग करने का प्रयास करना है।

टूटे हुए कनेक्शन अंत-बिंदुओं के बीच बहने वाले डेटा के बिना पता लगाना मुश्किल हो सकता है, जो इस विकल्प को बेकार कनेक्शन का पता लगाने के लिए डेटा का उपयोग नहीं करता है। हालांकि, देखने के लिए अपने कोड में जोड़ना आसान है। यह जोड़ें और देखें कि क्या वह मदद करता है ...

यह है कि यह कैसे सी में किया है या सी ++

int opt = 1; 
// Get the native socket handle from your socket class here... 
int socket_handle = getNativeSocketHandle(self.outputStream); 

/*Enabling keep alive*/ 
if(setsockopt(socket_handle, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)) < 0) 
{ 
    // failed setting socket option 
} 

नहीं-तो-सरल उत्तर अपने प्रोटोकॉल के लिए एक ping पैकेट जोड़ सकते हैं और है कि पिंग भेजने के लिए है नियमित रूप से पैकेट ताकि आप टूटे हुए कनेक्शन का पता लगा सकें।

+0

हम्म। उद्देश्य-सी में ऊपर दिए गए एपीआई का उपयोग करके ऐसा करने का कोई तरीका है? – Hahnemann

+0

@ हनीमैन: मुझे उद्देश्य-सी अच्छी तरह से पता नहीं है, इसलिए मुझे नहीं पता। हालांकि, मैं शर्त लगाने के लिए तैयार हूं कि सी libs को कॉल करने के लिए एक बच निकलना है। – JimR

+0

@ हननेमैन: यहां एक नज़र डालें: http://developer.apple.com/library/ios/DOCUMENTATION/CoreFoundation/Reference/CFStreamConstants/Reference/reference.html#//apple_ref/doc/c_ref/kCFStreamPropertySocketNativeHandle और देखें कि क्या यह है मदद करता है. – JimR

3

आपको नियमित रूप से कनेक्शन पर कुछ कचरा भेजने की आवश्यकता है। इस प्रयास करें:

NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:240 target:self selector:@selector(timerMethod:) userInfo:[NSNumber numberWithInt:sockfd] repeats:YES]; 

फिर self में यह घोषणा करते हैं:

-(void)timerMethod:(NSTimer*)t 
{ 
    send([[t userInfo] intValue], "Keepalive!", 11, 0); 
} 

नोट: बदलें `" KeepAlive! " जो भी आप अपने प्रोटोकॉल के लिए चाहते हैं। एकमात्र आवश्यकता यह है कि रिमोट एंड (सॉकेट सर्वर) संदेश को अनदेखा करता है।

+0

क्या है वहाँ एक सेट बाहर समय सीमा नहीं है कि मैं क्या आवृत्ति मैं कचरा डेटा भेजना चाहिए पर सोच रहा हूँ –

+0

@। उपयोगकर्ता: कनेक्शन के मरने में कितना समय लगता है? इसे पहले थोड़ा सा शेड्यूल करें। – Linuxios

+1

कुछ मामलों में, "कचरा" के बजाय, आप इसे सॉकेट सर्वर पर "दिल की धड़कन डेटा" के रूप में मानना ​​चाहेंगे। UPVOTED!:) –

3

एनएसओटपुटस्ट्रीम * ओस्ट्रीम मानना;

iOS पर यह इस तरह से कार्य करें:

#if 1 // Using CF 
CFDataRef data = (CFDataRef)CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)oStream, kCFStreamPropertySocketNativeHandle); 
if(data) { 
    CFSocketNativeHandle socket_handle = *(CFSocketNativeHandle *)CFDataGetBytePtr(data); 
    CFRelease(data); 
#else // Using Foundation 
NSData *data = (NSData *)[oStream propertyForKey:(__bridge NSString *)kCFStreamPropertySocketNativeHandle]; 
if(data) { 
    CFSocketNativeHandle socket_handle = *(CFSocketNativeHandle *)[data bytes]; 
#endif 
    NSLog(@"SOCK HANDLE: %x", socket_handle); 

    /*Enabling keep alive*/ 
    if(setsockopt(socket_handle, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)) < 0) 
    { 
     NSLog(@"Yikes 2: failed to set keepalive! ERRNO: %s", strerror(errno)); 
    } 

मैं यह सब काम मैं सिर्फ खर्च घंटे के बाद से इस पोस्टिंग कर रहा हूँ, किसी और प्रयास को बचाने के लिए चाहते हैं।

+0

सॉकेट_हैंडल, SOL_SOCKET, SO_KEEPALIVE के मान क्या हैं? – Rohan

+0

मैन 2 सेटॉकटॉप या एक्सकोड दस्तावेज़ दृश्य में सेटॉकटॉप पर खोजें। –

+2

केवल ऐप्पल कुछ इतना आसान, जटिल बना सकता है। मैंने बर्कले सॉकेट का उपयोग करके नेटवर्क किए गए ऐप्स प्रोग्राम किए हैं और यह इससे कम जटिल है। – deusprogrammer