1

我想将推送消息广播到多个设备。目前,如果数据库表中仅存储 2 个(可能是 1 个或 2 个)设备令牌,我可以发送消息。对于 3 个或更多设备令牌,我无法发送推送消息。它甚至不会向之前添加的 2 个设备发送消息。在服务器端,我可以看到消息已送达,但实际上并未送达。

我在开发人员配置文件和分发配置文件上对其进行了测试,但是如果数据库表中只有 1 或 2 个设备,我只能发送消息。

在这两种情况下,我都使用了一个为开发和分发而配置的应用程序 ID。

我的服务器端 php 代码如下:

<?php
error_reporting(0);
 include 'classfiles/Tokens.php';

if(isset($_POST))
{

$sender = $_POST['sender'];
$message = $_POST['message'];


$token = new Tokens;
$arrtokens = $token->getTokens();


$devicetoken = $_POST['device_token'];

// Settings
$apnsCert = 'test.pem';//To be changed
$apnsHost = 'gateway.push.apple.com';//To be changed
$apnsPort = 2195;

// Connect to Apple Push Notification server
$streamContext = stream_context_create();
stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
stream_context_set_option($streamContext, 'ssl', 'passphrase', 'test123');
//60 -> timeout in seconds
$apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
if (!$apns) {
    die('Error creating ssl socket');
}

stream_set_blocking ($apns, 0);

echo 'Connected to APNS' . PHP_EOL;

if(is_array($arrtokens))
{
    //foreach($arrtokens as $key=>$deviceToken)
    for($i=0;$i<count($arrtokens);$i++)
    {

        $incrementcount = 0;
        $tokenid = $arrtokens[$i][0];
        $badgecount = $arrtokens[$i][1];
        $incrementcount = $badgecount+1;

        // Prepare payload
        $payload = 
        array(
            'aps' => array(
            'alert' => $message,
            'badge' => $incrementcount,
            'sound' => 'default',
            'sender' => $sender
            )
        );
        $payload = json_encode($payload);

   /*
        // this was also working 

        $apnsMessage =
            chr(1)
            . pack('N', 88)
            . pack('N', time() + 86400)
            . chr(0) . chr(32) 
            . pack('H*', str_replace(' ', '', $tokenid)) 
            . chr(0) . chr(strlen($payload)) 
            . $payload . $payload;
   */

        $apnsMessage = chr(0) .pack('n',32) . pack('H*', str_replace(' ', '', $tokenid)) . chr(0) . chr(strlen($payload)) . $payload;

        // this was also working
        //   $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $tokenid)) . chr(0) . chr(strlen($payload)) . $payload;

        // this was also working
        //  $apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $device_tokens_array[i])) . chr(0) . chr(strlen($payload)) . $payload;

      //  $result =fwrite($apns, $apnsMessage);



            $result = fwrite($apns, $apnsMessage, strlen($apnsMessage));



        if(!$result)
        {
            echo 'Message to the device ' . $arrtokens[$i][0] . ' not delivered' . '<br/>';
        }else
        {
            $token->updateToken($tokenid,$incrementcount);  
            echo 'Message to the device ' . $arrtokens[$i][0] . ' successfully delivered' . '<br/>';

        }


    //  sleep(10);


    }
}
else if($devicetoken != "")
{
    $apnsMessage = 
            chr(1)
            . pack('N', 88)
            . pack('N', time() + 86400)
            . chr(0) . chr(32) 
            . pack('H*', str_replace(' ', '', $deviceToken)) 
            . chr(0) . chr(strlen($payload)) 
            . $payload . $payload;

    $result = fwrite($apns, $apnsMessage);
    if(!$result)
        echo 'Message to the device ' . $token . ' not delivered' . PHP_EOL;
    else
        echo 'Message to the device ' . $token . ' successfully delivered' . PHP_EOL;
}


usleep(500000);

fclose($apns);

}

function checkAppleErrorResponse($apns)
{
$responseBinary = fread($apns, 6);
if ($responseBinary !== false && strlen($responseBinary) == 6)
{
    print(
        "\n"
        .'Error message recieved from Apple.'."\n"
        .'For the meaning, refer to: "Provider Communication with Apple Push Notification Service"'."\n"
    );
    $response = unpack('Ccommand/Cstatus_code/Nidentifier', $responseBinary);
    var_dump($response);
}
}

?>

我的客户端代码在这里:

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"error : %@", [error description]);
}


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"deviceToken : %@", deviceToken);

NSString *myDeviceToken = [[[deviceToken description]
                            stringByReplacingOccurrencesOfString: @"<" withString: @""] 
                           stringByReplacingOccurrencesOfString: @">" withString: @""];

NSLog(@"%@",myDeviceToken);
[[NSUserDefaults standardUserDefaults] setObject:myDeviceToken forKey:@"myDeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];

receivedData = [[NSMutableData alloc] initWithLength:0];
NSString        *urlString  = [NSString stringWithFormat:@"%@%@", tokenApi, myDeviceToken];//deviceToken
urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSLog(@"URL : %@", urlString);
NSURL           *url        = [NSURL URLWithString:urlString];
NSURLRequest    *request    = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone) {
    NSLog(@"UIRemoteNotificationTypeNone");
} else if (types == UIRemoteNotificationTypeAlert) {
    NSLog(@"UIRemoteNotificationTypeAlert");
} else if (types == UIRemoteNotificationTypeBadge) {
    NSLog(@"UIRemoteNotificationTypeBadge");
} else if (types == UIRemoteNotificationTypeSound) {
    NSLog(@"UIRemoteNotificationTypeSound");
}

UIApplicationState state = [application applicationState];
int batchNo = [[UIApplication sharedApplication] applicationIconBadgeNumber];

if (state == UIApplicationStateActive) {
    NSLog(@"applicationIconBadgeNumber : %d", [[UIApplication sharedApplication] applicationIconBadgeNumber]);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[[userInfo objectForKey:@"aps"] objectForKey:@"sender"]
                                                     message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]
                                                    delegate:self 
                                           cancelButtonTitle:@"OK"
                                           otherButtonTitles:nil];
    [alert show];

    batchNo     = 0;
} else {
    NSLog(@"applicationIconBadgeNumber : %d", [[UIApplication sharedApplication] applicationIconBadgeNumber]);
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:batchNo - 1];
    batchNo     = [[UIApplication sharedApplication] applicationIconBadgeNumber];
}


NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:@"myDeviceToken"];
receivedData = [[NSMutableData alloc] initWithLength:0];
NSString        *urlString  = [NSString stringWithFormat:@"%@%@&count=% d", updateTokenApi, token,batchNo];//deviceToken
urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSLog(@"URL : %@", urlString);
NSURL           *url        = [NSURL URLWithString:urlString];
NSURLRequest    *request    = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];

//    NSLog(@"userInfo : %@", userInfo);
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"alerts"]];
//    NSLog(@"Before : %@", array);

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM/dd/YYYY hh:mm a"];

NSMutableArray *alertarray = [[NSMutableArray alloc] initWithCapacity:0];
[alertarray addObject:[dateFormatter stringFromDate:[NSDate date]]];
[alertarray addObject:[[userInfo objectForKey:@"aps"] objectForKey:@"sender"]];
[alertarray addObject:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]];
[array addObject:alertarray];

NSArray *alertsArray = [[NSArray alloc] initWithArray:array];

[[NSUserDefaults standardUserDefaults] setObject:alertsArray forKey:@"alerts"];
[[NSUserDefaults standardUserDefaults] synchronize];

[[[[self accountPage] accountHistoryPage] alertsArray] removeAllObjects];
[[[[self accountPage] accountHistoryPage] alertsArray] addObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"alerts"]];
[[[[self accountPage] accountHistoryPage] accountDetailTableView] reloadData];


//     NSLog(@"After : %@", [[NSUserDefaults standardUserDefaults] objectForKey:@"alerts"]);
}
4

1 回答 1

4

最可能的解释是第三个设备令牌无效。如果您首先发送到此设备令牌,Apple 会关闭套接字,并且忽略发送到其他两个设备的消息,即使它们似乎在服务器端已成功传递。如果您正在混合开发和生产设备令牌,那就可以解释为什么其中一些是无效的。如果您使用生产证书打开到 APNS 服务器的套接字,则只有生产设备令牌对该连接有效(反之亦然)。

于 2013-01-06T23:46:01.450 回答