Je configure des Websockets AWS API Gateway avec un autorisateur personnalisé sur la route $ connect, comme décrit ici:
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é?
7 Réponses :
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.
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"}
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?
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):
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
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.
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?
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>
{"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:
{"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.
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.
Pour ajouter du contenu à la demande d'intégration, vous devez utiliser un modèle de demande.
\ $ default
. Notez la barre oblique. Documentation complète ici .) $ default
. Notez l'absence de barre oblique.) { "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
.)
Vous pouvez obtenir le connectionId à partir de event.requestContext.
exports.handler = async (event) => { const data = event['body']; const connectionId = event['requestContext']['connectionId'];};
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:
Décochez Utiliser l'intégration du proxy
Enregistrer
Définissez le modèle de demande comme dans l'image suivante:
Cela permettra d'obtenir connectionId, query, body dans le corps de la requête.
Enregistrer
Cliquez sur Ajouter une réponse d'intégration en haut à droite
Définissez Réponse d'intégration comme dans l'image suivante:
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.
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?