【问题标题】:Problems sending bulk iOS notifications发送批量 iOS 通知时出现问题
【发布时间】:2017-10-01 05:08:17
【问题描述】:

我在为 iOS 设备发送批量通知时遇到问题,当我发送一些设备(或多或少 1-20 个)时它可以正常工作,但是当我必须发送批量发送(3000+)时它是给我以下错误:

[2017-04-27 15:12:07] 错误(通知:347)-IOS:Enenvio 错误 通知 - 通信异常: javapns.communication.exceptions.CommunicationException:通信 异常:java.net.ConnectException:过期???时代 conxi??连接超时)在 javapns.communication.ConnectionToAppleServer.getSSLSocket(ConnectionToAppleServer.java:156) 在 javapns.notification.PushNotificationManager.initializeConnection(PushNotificationManager.java:106) 在 javapns.notification.transmission.NotificationThread.runList(NotificationThread.java:215) 在 javapns.notification.transmission.NotificationThread.run(NotificationThread.java:199) 在 java.lang.Thread.run(Thread.java:745) 引起: java.net.ConnectException:过期??? tiempo de conexi????连接定时 出) 在 java.net.PlainSocketImpl.socketConnect(Native Method) 在 java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) 在 java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) 在 java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) 在 java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) 在 java.net.Socket.connect(Socket.java:576) 在 sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:635) 在 sun.security.ssl.SSLSocketImpl.(SSLSocketImpl.java:423) 在 sun.security.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:88) 在 javapns.communication.ConnectionToAppleServer.getSSLSocket(ConnectionToAppleServer.java:153) ... 4 更多

我的代码如下:

private static  void realizaEnvioIOSLista (final List<DispositivoDto> dispositivos, final String textoES, final String textoCA, final String textoEN, final String tipoNotificacion){       

        Thread thread = new Thread(){
            public void run(){              
                try {           
                    final List<String> idsDispositivos = new ArrayList<String>();                   

                    final String keystore = XmlUtils.dirCertIOS + XmlUtils.nomCertificado;
                    final String password = XmlUtils.password;
                    final boolean production = XmlUtils.production;

                    //Obtenemos los ids de los dispositivos
                    for(DispositivoDto r : dispositivos)
                         idsDispositivos.add(r.getIdDispositivo());                  

                    PushNotificationPayload payload = PushNotificationBigPayload.complex();

                    /* Customize the payload */ 
                    payload.addAlert(textoES);    
//                  payload.addSound('default');
                    payload.setContentAvailable(true);

                    payload.addCustomDictionary("es", textoES);
                    payload.addCustomDictionary("en", textoCA);
                    payload.addCustomDictionary("ca", textoEN);
                    payload.addCustomDictionary("tiponotificacion", tipoNotificacion);  

                    List<PushedNotification> notifications = new ArrayList<PushedNotification>();

                    if(idsDispositivos.size()<= 200){   
                        notifications = Push.payload(payload, keystore, password, production, idsDispositivos);

                    } else {
                        int threads = 1;

                        if(dispositivos.size() > 200) {
                            threads = (int) Math.ceil(dispositivos.size()/200);
                        }

                        notifications = Push.payload(payload, keystore, password, production, threads, idsDispositivos);  
                    }

                    int dispEliminados = 0;
                    int dispNotificados = 0;

                    for (PushedNotification notification : notifications) {
                        if (notification.isSuccessful()) {
                            dispNotificados ++;
                        } else {
                            String invalidToken = notification.getDevice().getToken();

                            int index = idsDispositivos.indexOf(invalidToken);

                            Integer usuario = dispositivos.get(index).getUsuario();
                            String idHardware = dispositivos.get(index).getIdHardwareDis();

                            aBD.unregisterDispositivo(usuario, invalidToken,idHardware);
                            dispEliminados ++;

        //                  Exception theProblem = notification.getException();
        //                  theProblem.printStackTrace();

                            //If the problem was an error-response packet returned by Apple, get it
                            ResponsePacket theErrorResponse = notification.getResponse();

                            if (theErrorResponse != null){
                                logNot.info("IOS: " +theErrorResponse.getMessage());
                            }
                        }
                    }   
                    logNot.info("IOS: Dispositivos Notificados correctamente: " + dispNotificados);
                    logNot.info("IOS: Dispositivos Eliminados: " +dispEliminados);

                } catch (CommunicationException e) {
                    logNot.error("IOS: Error en envio notificaciones - CommunicationException: ",e);
                } catch (KeystoreException e) {
                    logNot.error("IOS: Error en envio notificaciones - KeystoreException: ",e);
                } catch (JSONException e) {
                    logNot.error("IOS: Error en envio notificaciones - JSONException: ",e);
                } catch (Exception e) {
                    logNot.error("IOS: Error en envio notificaciones",e);
                }
            }
        };

        thread.start();
    }

有什么问题吗? Apple 服务器最多可以连接多少台设备和连接?欢迎任何帮助。

【问题讨论】:

    标签: java ios push-notification payload


    【解决方案1】:

    我找到了我的问题的解决方案,代码运行正常,在与系统管理员交谈后我们可以看到这是服务器配置的问题,因为根据apple的这个链接能够发送通知,必须考虑以下几点:

    要使用 Apple 推送通知服务 (APN),您的 Mac 和 iOS 客户端需要与 Apple 的服务器建立直接且持久的连接。

    这样:

    如果您在防火墙后使用 Wi-Fi,或使用私有接入点名称 蜂窝数据,连接到特定端口。您需要一个直接的、无代理的 在这些端口上连接到 APNs 服务器:

    • TCP 端口 5223 与 APN 通信。
    • TCP 端口 2195 向 APNs 发送通知。
    • 用于 APNs 反馈服务的 TCP 端口 2196。
    • 在设备激活期间需要 TCP 端口 443,然后如果设备无法通过端口 5223 访问 APN,则用于回退(仅在 Wi-Fi 上)。

    此外:

    APNs 服务器使用负载平衡,因此您的设备并不总是 连接到相同的公共 IP 地址以获取通知。最好是 让您的设备访问整个 17.0.0.0/8 地址上的这些端口 块,分配给 Apple。

    因此,系统管理员已通过配置防火墙来允许这些连接,从而解决了所有问题。我希望它可以帮助某人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多