【问题标题】:iOS socket based chat, how to receive messages that were sent when app is in the background?基于 iOS 套接字的聊天,如何接收应用程序在后台时发送的消息?
【发布时间】:2013-10-28 09:15:55
【问题描述】:

为了好玩,我构建了一个基于套接字的小聊天应用程序。它通过 tcp 套接字与 nodejs 服务器通话。它成功地来回发送消息。但是,当我按下主页按钮并将我的应用程序置于后台时会出现问题 - 此时套接字似乎已“暂停”并且在此期间发送的所有消息都丢失了。

我已经设置了应用程序在后台时的推送通知,但由于套接字在应用程序中未激活,因此消息永远不会真正到达应用程序。

我应该如何处理?我有哪些选择? 我有一些想法,但我喜欢这里关于人们如何处理这个问题的一些意见。

我的想法:

  1. 在我的 nodejs 服务器上添加一个“loadHistory”方法,用于发送频道的所有历史记录。这样我的应用程序就可以调用某个 URL 并获得一个 包含所有消息的 JSON 格式响应。也许每次触摸表格项目时都应该这样做?

  2. 利用iOS7新的后台运行功能? (我不确定它是否可以让套接字保持活动状态)

  3. 实现一种方法让服务器知道消息是否已送达,如果无法送达,则将消息存储在 数据库。一旦客户端再次上线,它就会发送 通过 tcp 的消息。这将需要大量附加功能 服务器所以我想尽可能避免这种情况。

【问题讨论】:

    标签: ios iphone objective-c


    【解决方案1】:

    如果要离线消息,则需要第三种方式,对于您收到的每条消息,您都需要向服务器发送一个通知,告诉它消息已传递,当您连接时,您应该获取丢失的消息.

    您可以使用 voip,但如果您的应用程序被杀死,您的应用程序将无法接收消息。 (如果你添加了 voip 模式但你的应用不是语音,苹果会屏蔽你的应用)

    【讨论】:

    • 是的,也许这实际上是最好的解决方案。也会使用更少的电池。
    • 我认为这是对的。您的应用可能会崩溃或有人可能会进入飞行模式...最可靠的方法是在重新连接时获取丢失的消息。
    • 也就是说,当您的应用程序处于后台时,要求几分钟的处理时间是有意义的,这样您就可以在用户转到另一个应用程序一分钟并返回时收到消息,但您需要做更多的工作.
    • 您也可以使用推送通知让用户知道收到的消息。
    【解决方案2】:

    我还在 TCP 套接字上做了一些工作。我通过这些步骤提供了后台支持:

    1. 在您的 plist 文件中添加“必需的背景模式”键。

    2. 将此代码添加到您的 AppDelegate.m 文件中

      - (void)applicationDidEnterBackground:(UIApplication *)application
      {
      #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 40000
          if([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] && [[UIDevice currentDevice] isMultitaskingSupported])
          {
              NSLog(@"Keep timeout alive");
      
              [application setKeepAliveTimeout:600 handler: ^{
                  NSLog(@"applicationDidEnterBackground:: setKeepAliveTimeout:handler^");//task as you want to do
              }];
          }
      
      #else
          LogInfo(@"applicationDidEnterBackground (Not supported)");
      #endif
      }
      
    3. 当你在 TCP 连接成功后得到你的读写 CFStream 套接字对象时,添加这段代码

      CFReadStreamSetProperty(yourCFReadStreamObj, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
      CFWriteStreamSetProperty(yourCFWriteStreamObj, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
      

    在完成这些步骤之后,您的套接字也应该在后台接收消息,并且连接将处于活动状态,直到您在“applicationDidEnterBackground”中给出的时间。

    我希望这会有所帮助。谢谢

    【讨论】:

    • 这将如何影响手机的电池寿命?
    • 这取决于您的应用程序在后台运行时的繁忙程度。我认为它不会像 LocationManager 在后台那样使用太多电池。
    • 您应该只对 VoIP 应用程序使用 VoIP 设置!当然,保持无线电/wifi打开/激活会损坏电池。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2014-10-31
    • 1970-01-01
    相关资源
    最近更新 更多