7
votes

AWS API Gateway Websockets - où se trouve l'ID de connexion?

Je configure des Websockets AWS API Gateway avec un autorisateur personnalisé sur la route $ connect, comme décrit ici:

https: //docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-route-keys-connect-disconnect.html

Ma question est la suivante: comment obtenir l'identifiant de connexion, c'est-à-dire l'identifiant que je peux utiliser pour diffuser ultérieurement vers ce client connecté?


1 commentaires

comment obtenir connectionID dans $ connect en utilisant le type d'intégration HTTP ass? J'ai essayé la réponse donnée mais j'obtiens une erreur.Pouvez-vous aider à résoudre ce problème?


7 Réponses :


0
votes

Vous pouvez obtenir connectionId à partir de variables de contexte. Voir ceci pour les variables disponibles pour les API WebSocket: https: // docs. aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-mapping-template-reference.html

Dans une fonction Lambda, vous pouvez accéder aux variables de contexte via event.requestContext.


0 commentaires

6
votes

Le problème ici était lors de l'utilisation de HTTP comme type d'intégration - c.-à-d. avoir des points de terminaison http lorsqu'un ou plusieurs de vos routes API GW sont invoquées ($ connect / $ disconnect / $ invoke). Nous avons constaté que nous ne pouvions pas proxy la demande (ce qui signifie que nous perdons les en-têtes d'origine, y compris auth), mais si nous avons besoin de l'ID de connexion, nous devons spécifier un modèle de demande et utiliser quelque chose comme:

{"connectionId": "$ context.connectionId", "body": "$ input.body"}


1 commentaires

Selon ce document: docs.aws .amazon.com / apigateway / latest / developerguide /… / Route Selection Expression section, $ request.body peut être utilisé mais j'obtiens toujours "". Pouvez-vous expliquer pourquoi?



2
votes

La question ne précise pas quel type de back-end est utilisé. La documentation AWS pour AWS API Gateway est orientée vers les fonctions lambda - je n'ai trouvé aucune aide pour obtenir le connectionId à mon back-end http.

En essayant la réponse de Big Endian, j'ai trouvé quelques problèmes - mon back-end cakephp ne le ferait pas décoder le corps json cité. J'ai trouvé la solution, mais il y avait de nombreuses autres étapes nécessaires pour implémenter sa réponse, alors les voici:

J'ai créé une clé de route avec le proxy HTTP désactivé, et mis en place un modèle de requête comme suit (également très documentation éparse):

  • Expression de sélection d'itinéraire: $ request.body.action
  • Clé d'itinéraire: s'abonner
    Cela signifie que toutes les demandes avec {"action": "subscribe"} seront acheminées par ici

  • Type de demande d'intégration: HTTP

  • Intégration du proxy HTTP: désactivée - à l'en-tête ou au passage d'authentification
  • Méthode HTTP: POST

Et puis pour le plus dur: mettre en place le modèle de requête. Je voulais que toutes les demandes "d'abonnement" utilisent ce modèle et le seul moyen que j'ai trouvé de le faire est de définir l'expression de sélection de modèle sur la même chose que l'expression de sélection d'itinéraire: $ request.body.action, et de définir la clé de modèle sur "subscribe ".

Cela finit par être un double test pour le même contenu que l'API doit faire pour appliquer ce modèle - et si quelqu'un a une meilleure façon de le faire, veuillez commenter.

Et puis la dernière étape est de saisir ceci comme "Generate template" pour 'subscribe':

{"connectionId": "$context.connectionId", "body": "$input.body"}

Notez que dans mon cas, mon corps était json et le $ input .body n'est pas entre guillemets - le corps json est développé par le modèle. Je suppose que si le corps est juste une chaîne, alors le modèle sera

{"connectionId": "$context.connectionId", "body": $input.body}

mais alors le routage n'arrivera jamais ici car le routage a besoin de body pour contenir la clé d'action dans json.


1 commentaires

Merci pour la réponse, qui m'aide beaucoup! Pouvez-vous expliquer pourquoi vous avez utilisé $ input.body au lieu de $ request.body comme mentionné dans le document?



0
votes

Un grand merci à François Stark, extrêmement utile.

Grâce à mes propres expériences, j'ai trouvé que vous pouvez éviter d'avoir à faire correspondre des valeurs spécifiques de $ request.body.action en utilisant la route $ default et le format suivant: p>

  • Expression de sélection de modèle: \ $ default
  • Clé de modèle: \ $ default
  • Générer un modèle avec
{"connectionId": "$context.connectionId"}

Avec cette configuration, votre point de terminaison HTTP devrait obtenir l'identifiant de connexion en tant que données de corps dans toutes les valeurs de 'action' en utilisant une seule route.

De plus , pour obtenir les identifiants de connexion dans les routes $ connect et $ disconnect , le format du modèle de demande est le même, mais comme il n'y a pas de données de corps dans ces événements, vous pouvez omettre le corps:

  • Expression de sélection de modèle: \ $ default
  • Clé de modèle: \ $ default
  • Générer un modèle avec
{"connectionId": "$context.connectionId", "body": $input.body}

Avec cette configuration, votre point de terminaison HTTP devrait obtenir l'identifiant de connexion comme données de corps dans les événements $ connect et $ disconnect.


2 commentaires

Lorsque je fais une expression de sélection de modèle en utilisant \ $ default. la connexion socket ne s'établit pas.


J'ai eu un problème similaire avec fini par le résoudre en faisant une réponse d'intégration et une réponse de méthode (comme décrit ci-dessus), qui ne servent aucun but apparent autre que de permettre aux connexions de fonctionner.



9
votes

Pour ajouter du contenu à la demande d'intégration, vous devez utiliser un modèle de demande.

  1. Désactivez l'intégration du proxy HTTP pour votre route. (Vous ne pouvez pas modifier la demande autrement.)
  2. Enregistrez vos modifications. (la section Modèles de demande n'apparaîtra pas tant que vous ne l'aurez pas fait.)
  3. Définissez votre expression de sélection de modèle. Ceci est utilisé pour rechercher une valeur à partir de l'objet de demande entrante. (Si vous voulez faire correspondre toutes les demandes entrantes, entrez \ $ default . Notez la barre oblique. Documentation complète ici .)
  4. Définissez votre clé de modèle. Ceci est comparé à la valeur sélectionnée par l'expression de sélection de modèle. S'il s'agit d'une correspondance, le modèle est utilisé. (Si vous souhaitez faire correspondre toutes les demandes entrantes, entrez $ default . Notez l'absence de barre oblique.)
  5. Cliquez sur votre clé de modèle pour ouvrir l'éditeur de modèle. C'est ici que vous entrez votre modèle qui sera envoyé à votre point de terminaison d'intégration en tant que corps de la demande. Par exemple, si vous souhaitez transférer l'ID de connexion et les paramètres de requête entrants vers le point de terminaison d'intégration, vous pouvez utiliser ce qui suit:
{
    "myConnectionIdProperty": "$context.connectionId",
    "myQueryParams": $input.params()
}

La documentation des variables disponibles dans l'expression de modèle peut être trouvée ici .

(Notez que si $ request est une variable valide dans Expression de sélection de modèle, ce n'est pas une variable valide dans le modèle lui-même. Utilisez plutôt $ input .)


0 commentaires

0
votes

Vous pouvez obtenir le connectionId à partir de event.requestContext.

exports.handler = async (event) => {
const data = event['body'];
const connectionId = event['requestContext']['connectionId'];};


0 commentaires

1
votes

Merci à tous d'avoir essayé de documenter au nom d'AWS. C'est dommage qu'AWS ne le fasse pas bien.

Pour pouvoir envoyer des données depuis AWS Websocket API Gateway vers votre service intégré à l'aide de VPC Link, procédez comme suit:

  1. Décochez Utiliser l'intégration du proxy

  2. Enregistrer

  3. Définissez le modèle de demande comme dans l'image suivante: Configuration du modèle de demande d'AWS Websocket API Gateway

  4. Cela permettra d'obtenir connectionId, query, body dans le corps de la requête.

  5. Enregistrer

  6. Cliquez sur Ajouter une réponse d'intégration en haut à droite

  7. Définissez Réponse d'intégration comme dans l'image suivante: Configuration de la réponse d'intégration

8. Espérons que cela fonctionnera. Si ce n'est pas le cas, déterminez-le en testant puis inscrivez les réponses ici pour les autres. Parce qu'AWS ne prendrait pas la peine de mettre en place une bonne documentation. Merci.

Je suggérerais d'oublier tout autre type d'intégration et d'utiliser simplement lambda. Parce que le prochain problème auquel vous serez confronté est d'obtenir les paramètres de requête qui ont été passés au moment de la connexion dans l'intégration de la déconnexion.


0 commentaires