根据苹果文档,我们必须为其中一个应用程序套接字配置VoIP使用。我无法弄清楚如何配置C++套接字(因为有许多套接字;即SSL、SIP、RESTful)。
我的意图是将应用程序在睡眠模式下运行,直到被杀死。尝试了一些链接,甚至从SO中找到了一些链接,但由于我是新手,所以我想要一个逐步的配置过程。 [注:在某个地方我找到了CoreFoudation框架,我需要使用它吗?]
编辑:从iOS8开始,苹果公司推出了PushKit框架来释放我们需要进行配置的VoIP应用程序,并且它还可以减少能源使用。你真的需要迁移到它。
以下是开发VoIP应用程序的提示,参考自Apple官方文档
网络电话(VoIP)应用程序允许用户通过互联网连接而不是设备的蜂窝服务打电话。此类应用程序需要维护与其关联服务的持久网络连接,以便接收来电和其他相关数据。系统允许将VoIP应用程序挂起而不是一直保持唤醒状态,并为它们提供监视套接字的工具。当检测到传入流量时,系统会唤醒VoIP应用程序并将其套接字控制权交还给它。
实现VoIP应用程序有几个要求:
启用VoIP后台模式使系统知道它应该根据需要允许应用程序在后台运行以管理其网络套接字。此关键字还允许您的应用程序播放背景音频(虽然仍然鼓励启用音频和AirPlay模式)。支持此模式的应用程序也会在系统引导后立即在后台重新启动,以确保VoIP服务始终可用。
以下代码显示了如何为应用程序的套接字配置VoIP使用。
步骤1:连接到服务器
uint16_t port ;
NSString *strIp ;
char ip[20] = {0} ;
memset(ip, 0, sizeof(ip)) ;
memcpy(ip, [strIp UTF8String], [strIp length]) ;
clientSocket = socket(AF_INET, SOCK_STREAM, 0) ;
struct sockaddr_in server_addr ;
bzero(&server_addr, sizeof(server_addr)) ;
server_addr.sin_port = htons(port) ;
server_addr.sin_addr.s_addr = inet_addr(ip) ;
server_addr.sin_family = AF_INET ;
int i = connect(clientSocket, (const struct sockaddr *)&server_addr, sizeof(server_addr)) ;
if (i >= 0) {
}
服务器端代码可能在 C++ 环境中,但你可以将 clientSocket
传递给 Objective-C 实例,它是一个 int
值。
步骤2:创建和配置读写流
连接到服务器后,需要使用 CFStreamCreatePairWithSocket()
基于 clientSocket
创建读写流,并使用 NSStreamNetworkServiceTypeVoIP
设置流的属性。
定义读写流并保持强引用。当连接丢失时,关闭并释放它们。
@property (nonatomic, strong) NSInputStream *inputStream ;
@property (nonatomic, strong) NSOutputStream *outputStream ;
然后配置流:
CFReadStreamRef readStreamRef = nil ;
CFWriteStreamRef writeStreamRef = nil ;
CFStreamCreatePairWithSocket(NULL, clientSocket, &readStreamRef, &writeStreamRef) ; // the socket must have already been connected.
_inputStream = (__bridge_transfer NSInputStream *)readStreamRef ;
_outputStream = (__bridge_transfer NSOutputStream *)writeStreamRef ;
[_inputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType] ;
[_outputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType] ;
[_inputStream open] ;
[_outputStream open] ;
在使用读写流连接之前,请确保套接字已经连接。
第三步:保持连接
[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{
// the code to check if the socket is connected to server
// if not, reconnect to server
// and re-set the read stream and write stream in step2
}] ;
当您的应用程序进入后台时,套接字由系统管理,当服务器向您的应用程序发送数据包时,系统会唤醒它并将数据包传递给它。您只有几秒钟来处理数据,因此不要在这里做太多的工作。由于这是一个VoIP应用程序,所以应该使用套接字来通知用户有来电,并可以推送本地通知以让用户知道。connect
成功后,您应该传递套接字并使用CFStreamCreatePairWithSocket
函数创建读写流,然后配置这些流。 - KudoCC除了配置套接字外,您还需要对iOS应用程序的Info.plist文件进行一些更改,在其中指定voip
后台模式。
更多详细信息可以在此处找到:Apple Dev文档
NSApplication setKeepAliveTimeout:handler:
。这应该使您能够控制后台中套接字保持打开的时间。 - RomanNSApplication setKeepAliveTimeout:handler:
用于维护其服务连接:向服务器发送保持活动数据包。 - KudoCC