各位大神,首次开发iOS项目,需要用到Socket通讯,现服务端已写好,客户端用以下这个工程源码可以正常连接服务端并返回数据。但客户端程序在切换到后台后,Socket通讯被停止,不一会儿就断开了。baidu查资料,说需要用到 voip 实现后台长连接:iOS应用中通过设置VOIP模式实现休眠状态下socket的长连接
voip与socket实现后台推送但小弟对Xcode环境及语法不熟,无法根据文档完成,哪位大神帮忙实现或指导下?客户端Socket源码

解决方案 »

  1.   


    - (void)_initializeStreams;
    {
        assert(_url.port.unsignedIntValue <= UINT32_MAX);
        uint32_t port = _url.port.unsignedIntValue;
        if (port == 0) {
            if (!_secure) {
                port = 80;
            } else {
                port = 443;
            }
        }
        NSString *host = _url.host;
        
        CFReadStreamRef readStream = NULL;
        CFWriteStreamRef writeStream = NULL;
        
        CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
        
        _outputStream = CFBridgingRelease(writeStream);
        _inputStream = CFBridgingRelease(readStream);
        
        
        if (_secure) {
            NSMutableDictionary *SSLOptions = [[NSMutableDictionary alloc] init];
            
            [_outputStream setProperty:(__bridge id)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel];
            
            // If we're using pinned certs, don't validate the certificate chain
            if ([_urlRequest SR_SSLPinnedCertificates].count) {
                [SSLOptions setValue:[NSNumber numberWithBool:NO] forKey:(__bridge id)kCFStreamSSLValidatesCertificateChain];
            }
            
    #if DEBUG
            [SSLOptions setValue:[NSNumber numberWithBool:NO] forKey:(__bridge id)kCFStreamSSLValidatesCertificateChain];
            NSLog(@"SocketRocket: In debug mode.  Allowing connection to any root cert");
    #endif
            
            [_outputStream setProperty:SSLOptions
                                forKey:(__bridge id)kCFStreamPropertySSLSettings];
        }
        
        // Set up the connections to be VOIP
        [_inputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
        [_outputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];

        
        _inputStream.delegate = self;
        _outputStream.delegate = self;
    }
    我在_initializeStreams方法里添加了这两句后,未加之前切换到后台几秒钟就断开了。切换到后台能正常执行一段时间,然后出现异常 lldb ,用 bt 得出异常信息如下:* thread #1: tid = 0x1bdbaf, 0x0000000190511ca0 libsystem_kernel.dylib`mach_msg_trap + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
      * frame #0: 0x0000000190511ca0 libsystem_kernel.dylib`mach_msg_trap + 8
        frame #1: 0x0000000190511b0c libsystem_kernel.dylib`mach_msg + 72
        frame #2: 0x00000001838f2d24 CoreFoundation`__CFRunLoopServiceMachPort + 184
        frame #3: 0x00000001838f0f18 CoreFoundation`__CFRunLoopRun + 936
        frame #4: 0x0000000183831dd0 CoreFoundation`CFRunLoopRunSpecific + 452
        frame #5: 0x0000000189519c0c GraphicsServices`GSEventRunModal + 168
        frame #6: 0x0000000186962fc4 UIKit`UIApplicationMain + 1156
        frame #7: 0x00000001001013f0 TestChat`main(argc=1, argv=0x000000016fd03c40) + 116 at main.m:16
        frame #8: 0x000000019042faa0 libdyld.dylib`start + 4
      

  2.   

     [_inputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
     [_outputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
      

  3.   

    Sep 21 22:26:22 Raozhivende-iPhone TestChat[8124] <Warning>: Received "{"DataType":-1}"
    Sep 21 22:26:32 Raozhivende-iPhone backboardd[31] <Warning>: BKUnsuspendLimit TestChat[8124] exceeded 15 wakes in 300 sec
    Sep 21 22:26:32 Raozhivende-iPhone backboardd[31] <Warning>: Forcing crash report of TestChat[8124]...
    Sep 21 22:26:32 Raozhivende-iPhone backboardd[31] <Warning>: Finished crash reporting.
    Sep 21 22:26:32 Raozhivende-iPhone wifid[40] <Error>: WiFi:[433002392.576092]: Disable WoW requested by "UserEventAgent"
    Sep 21 22:26:32 Raozhivende-iPhone com.apple.launchd[1] (UIKitApplication:com.squareup.TestChat[0x5017][8124]) <Notice>: (UIKitApplication:com.squareup.TestChat[0x5017]) Exited: Killed: 9
    Sep 21 22:26:32 Raozhivende-iPhone backboardd[31] <Warning>: Application 'UIKitApplication:com.squareup.TestChat[0x5017]' exited abnormally with signal 9: Killed: 9
    Sep 21 22:26:32 Raozhivende-iPhone SpringBoard[16] <Warning>: Encountered an XPC error while communicating with backboardd: <error: 0x193302cd0> { count = 1, contents =
    "XPCErrorDescription" => <string: 0x193303108> { length = 22, contents = "Connection interrupted" }
    }
    Sep 21 22:26:32 Raozhivende-iPhone SpringBoard[16] <Warning>: Memory level is not normal or this app was killed by jetsam. Pending auto-relaunch of 'com.squareup.TestChat'.
    Sep 21 22:26:32 Raozhivende-iPhone ReportCrash[8139] <Notice>: Saved crashreport to /var/mobile/Library/Logs/CrashReporter/TestChat_2014-09-21-222632_Raozhivende-iPhone.ips using uid: 0 gid: 0, synthetic_euid: 501 egid: 0
    Sep 21 22:26:41 Raozhivende-iPhone touchsetupd[110] <Warning>: WPTransfer deallocing
    Sep 21 22:26:41 Raozhivende-iPhone wirelessproxd[35] <Notice>: (Error) error event: (<OS_xpc_error: <error: 0x193302dc8> { count = 1, contents =
    "XPCErrorDescription" => <string: 0x1933030d0> { length = 18, contents = "Connection invalid" }
    }>)
    Sep 21 22:26:47 Raozhivende-iPhone kernel[0] <Debug>: launchd[8140] Container: /private/var/mobile/Applications/DF75FDF4-47DB-480F-BC2B-913F38C563EF (sandbox)
    Sep 21 22:26:47 Raozhivende-iPhone backboardd[31] <Error>: HID: The 'Passive' connection 'TestChat' access to protected services is denied.
      

  4.   

    Incident Identifier: C3BC2288-AF8E-45BA-858A-4719C4A01970
    CrashReporter Key:   148b6405ce4142f7b860893c12211ec245afd6c1
    Hardware Model:      iPhone6,1
    Process:             TestChat [8124]
    Path:                /var/mobile/Applications/DF75FDF4-47DB-480F-BC2B-913F38C563EF/TestChat.app/TestChat
    Identifier:          com.squareup.TestChat
    Version:             1.0 (1.0)
    Code Type:           ARM-64 (Native)
    Parent Process:      launchd [1]Date/Time:           2014-09-21 22:26:32.451 +0800
    OS Version:          iOS 7.1.2 (11D257)
    Report Version:      104Exception Type:  00000020
    Exception Codes: 0x00000000bad22222
    Highlighted Thread:  2Application Specific Information:
    BKUnsuspendLimit TestChat[8124] exceeded 15 wakes in 300 secThread 0:
    0   libsystem_kernel.dylib         0x0000000190511ca0 mach_msg_trap + 8
    1   CoreFoundation                 0x00000001838f2d20 __CFRunLoopServiceMachPort + 180
    2   CoreFoundation                 0x00000001838f0f14 __CFRunLoopRun + 932
    3   CoreFoundation                 0x0000000183831dcc CFRunLoopRunSpecific + 448
    4   GraphicsServices               0x0000000189519c08 GSEventRunModal + 164
    5   UIKit                          0x0000000186962fc0 UIApplicationMain + 1152
    6   TestChat                       0x00000001000a9268 main (main.m:16)
    7   libdyld.dylib                  0x000000019042fa9c start + 0Thread 1:
    0   libsystem_kernel.dylib         0x0000000190511aa8 kevent64 + 8
    1   libdispatch.dylib              0x0000000190415998 _dispatch_mgr_thread + 48Thread 2:
    0   libsystem_kernel.dylib         0x0000000190511ca0 mach_msg_trap + 8
    1   CoreFoundation                 0x00000001838f2d20 __CFRunLoopServiceMachPort + 180
    2   CoreFoundation                 0x00000001838f0eb0 __CFRunLoopRun + 832
    3   CoreFoundation                 0x0000000183831dcc CFRunLoopRunSpecific + 448
    4   Foundation                     0x00000001843cd2c0 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 292
    5   TestChat                       0x00000001000b7be0 -[_SRRunLoopThread main] (SRWebSocket.m:1738)
    6   Foundation                     0x00000001844b4408 __NSThread__main__ + 996
    7   libsystem_pthread.dylib        0x00000001905abe18 _pthread_body + 164
    8   libsystem_pthread.dylib        0x00000001905abd70 _pthread_start + 136
    9   libsystem_pthread.dylib        0x00000001905a9550 thread_start + 0Thread 3 name:  com.apple.NSURLConnectionLoader
    Thread 3:
    0   libsystem_kernel.dylib         0x0000000190511ca0 mach_msg_trap + 8
    1   CoreFoundation                 0x00000001838f2d20 __CFRunLoopServiceMachPort + 180
    2   CoreFoundation                 0x00000001838f0eb0 __CFRunLoopRun + 832
    3   CoreFoundation                 0x0000000183831dcc CFRunLoopRunSpecific + 448
    4   Foundation                     0x0000000184426424 +[NSURLConnection(Loader) _resourceLoadLoop:] + 344
    5   Foundation                     0x00000001844b4408 __NSThread__main__ + 996
    6   libsystem_pthread.dylib        0x00000001905abe18 _pthread_body + 164
    7   libsystem_pthread.dylib        0x00000001905abd70 _pthread_start + 136
    8   libsystem_pthread.dylib        0x00000001905a9550 thread_start + 0Thread 4 name:  com.apple.CFSocket.private
    Thread 4:
    0   libsystem_kernel.dylib         0x000000019052a76c __select + 8
    1   libsystem_pthread.dylib        0x00000001905abe18 _pthread_body + 164
    2   libsystem_pthread.dylib        0x00000001905abd70 _pthread_start + 136
    3   libsystem_pthread.dylib        0x00000001905a9550 thread_start + 0Thread 5:
    0   libsystem_kernel.dylib         0x000000019052ae74 __workq_kernreturn + 8
    1   libsystem_pthread.dylib        0x00000001905a9548 start_wqthread + 0No thread state (register information) available
    百度说,0xbad22222: 该编码表示 VoIP 应用因为过于频繁重启而被终止。
      

  5.   

    文章中提到了,需要打开Background Modes. 不知道你尝试之后的结果如何。打开后台模式应该可以让你的应用常驻