Creación de un punto de enlace de plataforma - Amazon Simple Notification Service

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Creación de un punto de enlace de plataforma

Cuando una aplicación y un dispositivo móvil se registran en un servicio de notificación de inserción, dicho servicio devuelve un token de dispositivo. Amazon SNS utiliza el token de dispositivo para crear un punto de enlace móvil al que puede enviar mensajes de notificación de inserción directos. Para obtener más información, consulte Requisitos previos para las notificaciones de usuario de Amazon SNS y Información general del proceso de notificación de usuario.

En esta sección se describe el procedimiento recomendado para crear un punto de enlace de plataforma.

Creación de un punto de enlace de plataforma

Para insertar notificaciones en una aplicación con Amazon SNS, primero debe registrarse el token de dispositivo de la aplicación en Amazon SNS llamando a la acción de creación del punto de enlace de plataforma. Esta acción toma el nombre de recurso de Amazon (ARN) de la aplicación de plataforma y el token de dispositivo como parámetros y devuelve el ARN del punto de enlace de plataforma creado.

La acción de creación de punto de enlace de plataforma hace lo siguiente:

  • Si el punto de enlace de plataforma ya existe, no lo vuelva a crear. Devuelva al intermediario el ARN del punto de enlace de plataforma existente.

  • Si ya existe el punto de enlace de plataforma con el mismo token de dispositivo pero diferentes opciones, no lo vuelva a crear. Envíe una excepción al intermediario.

  • Si el punto de enlace de plataforma no existe, créelo. Devuelva al intermediario el ARN del punto de enlace de plataforma que acaba de crear.

No debe llamar a la acción de creación de un punto de enlace de plataforma inmediatamente cada vez que se inicie una aplicación; este enfoque no siempre proporciona un punto de enlace que funcione. Esto puede ocurrir, por ejemplo, cuando una aplicación se desinstala y se vuelve a instalar en el mismo dispositivo, y su punto de enlace que ya existe, pero está deshabilitado. Un proceso de registro correcto debe realizar las operaciones siguientes:

  1. Asegurarse de que exista un punto de enlace de plataforma para esta combinación de aplicación y dispositivo.

  2. Asegurarse de que el token de dispositivo del punto de enlace de plataforma es el último token de dispositivo válido.

  3. Asegurarse de que el punto de enlace de plataforma esté habilitado y listo para ser utilizado.

Pseudocódigo

El siguiente pseudocódigo describe una práctica recomendada para crear un punto de enlace de plataforma que funcione, sea actual y esté habilitado en una amplia variedad de condiciones de partida. Este enfoque funciona tanto si se trata de la primera vez que la aplicación se registra o no, como si el punto de enlace de plataforma de esta aplicación ya existe, o si el punto de enlace de plataforma está habilitado, tiene el token de dispositivo correcto, etc. Es seguro llamarlo varias veces seguidas, ya que no creará puntos de enlace de plataforma duplicados ni cambiará un punto de enlace de plataforma si ya está actualizado y activado.

retrieve the latest device token from the mobile operating system if (the platform endpoint ARN is not stored) # this is a first-time registration call create platform endpoint store the returned platform endpoint ARN endif call get endpoint attributes on the platform endpoint ARN if (while getting the attributes a not-found exception is thrown) # the platform endpoint was deleted call create platform endpoint with the latest device token store the returned platform endpoint ARN else if (the device token in the endpoint does not match the latest one) or (get endpoint attributes shows the endpoint as disabled) call set endpoint attributes to set the latest device token and then enable the platform endpoint endif endif

Este enfoque se puede utilizar siempre que la aplicación quiera registrarse o volver a registrarse. También se puede utilizar para notificar a Amazon SNS un cambio en el token del dispositivo. En este caso, solo tiene que llamar a la acción con el valor de token del último dispositivo. Tenga en cuenta los elementos siguientes de este enfoque:

  • Hay dos casos en los que puede llamar a la acción de crear un punto de enlace de plataforma. Puede llamarse justo al principio, cuando la aplicación no conoce su propio ARN de punto de enlace de plataforma, como es el caso durante un primer registro. También se puede llamar si la llamada inicial de acción de obtención de los atributos del punto de enlace genera un error con una excepción del tipo no se ha encontrado, como ocurriría si la aplicación conoce su ARN de punto de enlace, pero este se ha eliminado.

  • Se llama a la acción de obtención de los atributos del punto de enlace para verificar el estado del punto de enlace de plataforma, aunque dicho punto de enlace se acabe de crear. Esto ocurre cuando el punto de enlace de plataforma ya existe, pero está deshabilitado. En este caso, la acción de creación del punto de enlace de plataforma se realiza correctamente, pero no habilita el punto de enlace de plataforma, por lo que debe comprobar el estado del punto de enlace de plataforma antes de devolver el resultado correcto.

Ejemplos del AWS SDK

Los siguientes ejemplos muestran cómo implementar el pseudocódigo anterior utilizando los clientes de Amazon SNS de que proporciona elAWSSDK.

nota

Recuerde configurar sus credenciales de AWS antes de usar el SDK. Para obtener más información, consulteConfiguraciónAWSCredencialesen laAWS SDK for .NETGuía para desarrolladores. O consulte,Uso de credencialesen laAWS SDK for JavaGuía para desarrolladores.

AWS SDK for Java

Aquí tiene una implementación del pseudocódigo anterior en Java:

class RegistrationExample { AmazonSNSClient client = new AmazonSNSClient(); //provide credentials here String arnStorage = null; public void registerWithSNS() { String endpointArn = retrieveEndpointArn(); String token = "Retrieved from the mobile operating system"; boolean updateNeeded = false; boolean createNeeded = (null == endpointArn); if (createNeeded) { // No platform endpoint ARN is stored; need to call createEndpoint. endpointArn = createEndpoint(); createNeeded = false; } System.out.println("Retrieving platform endpoint data..."); // Look up the platform endpoint and make sure the data in it is current, even if // it was just created. try { GetEndpointAttributesRequest geaReq = new GetEndpointAttributesRequest() .withEndpointArn(endpointArn); GetEndpointAttributesResult geaRes = client.getEndpointAttributes(geaReq); updateNeeded = !geaRes.getAttributes().get("Token").equals(token) || !geaRes.getAttributes().get("Enabled").equalsIgnoreCase("true"); } catch (NotFoundException nfe) { // We had a stored ARN, but the platform endpoint associated with it // disappeared. Recreate it. createNeeded = true; } if (createNeeded) { createEndpoint(token); } System.out.println("updateNeeded = " + updateNeeded); if (updateNeeded) { // The platform endpoint is out of sync with the current data; // update the token and enable it. System.out.println("Updating platform endpoint " + endpointArn); Map attribs = new HashMap(); attribs.put("Token", token); attribs.put("Enabled", "true"); SetEndpointAttributesRequest saeReq = new SetEndpointAttributesRequest() .withEndpointArn(endpointArn) .withAttributes(attribs); client.setEndpointAttributes(saeReq); } } /** * @return never null * */ private String createEndpoint(String token) { String endpointArn = null; try { System.out.println("Creating platform endpoint with token " + token); CreatePlatformEndpointRequest cpeReq = new CreatePlatformEndpointRequest() .withPlatformApplicationArn(applicationArn) .withToken(token); CreatePlatformEndpointResult cpeRes = client .createPlatformEndpoint(cpeReq); endpointArn = cpeRes.getEndpointArn(); } catch (InvalidParameterException ipe) { String message = ipe.getErrorMessage(); System.out.println("Exception message: " + message); Pattern p = Pattern .compile(".*Endpoint (arn:aws:sns[^ ]+) already exists " + "with the same [Tt]oken.*"); Matcher m = p.matcher(message); if (m.matches()) { // The platform endpoint already exists for this token, but with // additional custom data that // createEndpoint doesn't want to overwrite. Just use the // existing platform endpoint. endpointArn = m.group(1); } else { // Rethrow the exception, the input is actually bad. throw ipe; } } storeEndpointArn(endpointArn); return endpointArn; } /** * @return the ARN the app was registered under previously, or null if no * platform endpoint ARN is stored. */ private String retrieveEndpointArn() { // Retrieve the platform endpoint ARN from permanent storage, // or return null if null is stored. return arnStorage; } /** * Stores the platform endpoint ARN in permanent storage for lookup next time. * */ private void storeEndpointArn(String endpointArn) { // Write the platform endpoint ARN to permanent storage. arnStorage = endpointArn; } }

Una cosa interesante a tener en cuenta sobre esta implementación es cómo elInvalidParameterExceptionse gestiona en lacreateEndpointMétodo de. Amazon SNS rechaza las solicitudes de creación de puntos de enlace de plataforma cuando un punto de enlace de plataforma ya existente tenga el mismo token de dispositivo y un valor que no es nulo.CustomUserData, porque la alternativa es sobrescribir (y por lo tanto perder) el campoCustomUserData. LacreateEndpointen el código anterior captura el métodoInvalidParameterExceptionenviado por Amazon SNS, comprueba si se ha enviado por este motivo en concreto y, en caso afirmativo, extrae el ARN del punto de enlace de plataforma existente de la excepción. Esto se realiza correctamente, dado que existe un punto de enlace de plataforma con el token de dispositivo correcto.

Para obtener más información, consulte Acciones de inserción en móviles.

AWS SDK for .NET

Aquí tiene una implementación del pseudocódigo anterior en C#:

class RegistrationExample { private AmazonSimpleNotificationServiceClient client = new AmazonSimpleNotificationServiceClient(); private String arnStorage = null; public void RegisterWithSNS() { String endpointArn = EndpointArn; String token = "Retrieved from the mobile operating system"; String applicationArn = "Set this based on your application"; bool updateNeeded = false; bool createNeeded = (null == endpointArn); if (createNeeded) { // No platform endpoint ARN is stored; need to call createEndpoint. EndpointArn = CreateEndpoint(token, applicationArn); createNeeded = false; } Console.WriteLine("Retrieving platform endpoint data..."); // Look up the platform endpoint and make sure the data in it is current, even if // it was just created. try { GetEndpointAttributesRequest geaReq = new GetEndpointAttributesRequest(); geaReq.EndpointArn = EndpointArn; GetEndpointAttributesResponse geaRes = client.GetEndpointAttributes(geaReq); updateNeeded = !(geaRes.Attributes["Token"] == token) || !(geaRes.Attributes["Enabled"] == "true"); } catch (NotFoundException) { // We had a stored ARN, but the platform endpoint associated with it // disappeared. Recreate it. createNeeded = true; } if (createNeeded) { CreateEndpoint(token, applicationArn); } Console.WriteLine("updateNeeded = " + updateNeeded); if (updateNeeded) { // The platform endpoint is out of sync with the current data; // update the token and enable it. Console.WriteLine("Updating platform endpoint " + endpointArn); Dictionary<String,String> attribs = new Dictionary<String,String>(); attribs["Token"] = token; attribs["Enabled"] = "true"; SetEndpointAttributesRequest saeReq = new SetEndpointAttributesRequest(); saeReq.EndpointArn = EndpointArn; saeReq.Attributes = attribs; client.SetEndpointAttributes(saeReq); } } private String CreateEndpoint(String token, String applicationArn) { String endpointArn = null; try { Console.WriteLine("Creating platform endpoint with token " + token); CreatePlatformEndpointRequest cpeReq = new CreatePlatformEndpointRequest(); cpeReq.PlatformApplicationArn = applicationArn; cpeReq.Token = token; CreatePlatformEndpointResponse cpeRes = client.CreatePlatformEndpoint(cpeReq); endpointArn = cpeRes.EndpointArn; } catch (InvalidParameterException ipe) { String message = ipe.Message; Console.WriteLine("Exception message: " + message); Regex rgx = new Regex(".*Endpoint (arn:aws:sns[^ ]+) already exists with the same [Tt]oken.*", RegexOptions.IgnoreCase); MatchCollection m = rgx.Matches(message); if (m.Count > 0 && m[0].Groups.Count > 1) { // The platform endpoint already exists for this token, but with // additional custom data that createEndpoint doesn't want to overwrite. // Just use the existing platform endpoint. endpointArn = m[0].Groups[1].Value; } else { // Rethrow the exception, the input is actually bad. throw ipe; } } EndpointArn = endpointArn; return endpointArn; } // Get/Set arn public String EndpointArn { get { return arnStorage; } set { arnStorage = value; } } }

Para obtener más información, consulte Acciones de inserción en móviles.

Troubleshooting

Llamar repetidamente a la acción de creación de un punto de enlace de plataforma con un token de dispositivo obsoleto

Especialmente para los puntos de enlace FCM, puede que piense que es mejor almacenar el primer token de dispositivo generado por la aplicación y llamar a la creación de punto de enlace de plataforma con dicho token de dispositivo cada vez que se inicia la aplicación. Esto puede parecer correcto, dado que la aplicación no tiene que administrar el estado del token de dispositivo y Amazon SNS actualizará automáticamente el token de dispositivo a su valor más reciente. Sin embargo, esta solución presenta una serie de problemas graves:

  • Amazon SNS depende de los comentarios de FCM para actualizar los tokens de dispositivo caducados en tokens de dispositivo nuevos. FCM conserva información sobre tokens de dispositivo antiguos durante un tiempo, aunque no de forma indefinida. Cuando FCM se olvide de la conexión entre el token de dispositivo antiguo y el nuevo, Amazon SNS ya no podrá actualizar el token de dispositivo almacenado en el punto de enlace de plataforma en su valor correcto; en su lugar, deshabilitará el punto de enlace de plataforma.

  • La aplicación de plataforma contendrá varios puntos de enlace de plataforma correspondientes al mismo token de dispositivo.

  • Amazon SNS impone una cuota al número de puntos de enlace de plataforma que se pueden crear comenzando por el mismo token de dispositivo. Al final, la creación de los puntos de enlace nuevos generará un error con la excepción de parámetro no válido y el siguiente mensaje de error: «Este punto de conexión ya está registrado en un token diferente.»

Reactivación de un punto de enlace de plataforma asociado a un token de dispositivo no válido

Cuando una plataforma móvil (como APNs o FCM) informa a Amazon SNS de que el token de dispositivo utilizado en la solicitud de publicación no es válido, Amazon SNS deshabilita el punto de enlace de plataforma asociado a ese token de dispositivo. A continuación, Amazon SNS rechaza las publicaciones posteriores que se efectúen en ese token de dispositivo. Aunque le parezca que es mejor volver a activar el punto de enlace de plataforma y seguir publicando, en la mayoría de los casos esta solución no funciona: los mensajes que se publican no se entregan y el punto de enlace de plataforma se vuelve a desactivar poco después.

Esto se debe a que el token de dispositivo asociado al punto de enlace de plataforma en realidad no es válido. Las entregas que se le hacen no pueden realizarse correctamente, puesto que el token ya no corresponde a ninguna aplicación instalada. La siguiente vez que se publique en él, la plataforma móvil volverá a informar a Amazon SNS de que el token de dispositivo no es válido y Amazon SNS volverá a deshabilitar el punto de enlace de plataforma.

Para volver a habilitar un punto de enlace de plataforma desactivado, debe asociarlo a un token de dispositivo válido (con una llamada de acción de definición de los atributos del punto de enlace) y después habilitarlo. Solo entonces las entregas a dicho punto de enlace de plataforma se realizarán correctamente. La única vez en que volver a habilitar un punto de enlace de plataforma sin actualizar su token de dispositivo funcione será cuando un token de dispositivo que no era válido y estaba asociado a dicho punto de enlace vuelva a ser válido. Esto puede ocurrir, por ejemplo, cuando se desinstala una aplicación y se vuelve a instalar en el mismo dispositivo móvil y recibe el mismo token de dispositivo. El enfoque que acabamos de presentar realiza esta operación asegurándose de volver a habilitar un punto de enlace de plataforma solo después de comprobar que el token de dispositivo que tiene asociado es el más actual disponible.