Dieser Artikel ist der zweite Tag von NTT Technocross Adventskalender 2019.
Hallo. Ich heiße Yasuda. Ich bin verantwortlich für die Entwicklung neuer AI-Produkte bei NTT Techno Cross. Obwohl es sofort vom Hauptthema abweicht, ist das Zeichnen von Manga eine kürzliche Pause, und ich zeichne den folgenden Manga.
Datenverknüpfung von Manga verstanden Unternehmensarchitektur in der KI-Ära unter Manga verstanden Von Manga verstandene IT-Strategie
... Nun, in diesem Artikel möchte ich sehen, wie "Web Socket" ohne einen AWS-Server ausgeführt wird. Es scheint, dass AWS API Gateway seit Dezember 2018 die WebSocket-Kommunikation einrichten kann, und ich wollte es eines Tages ausprobieren, also habe ich es versucht. Als ich nachgeschlagen habe, habe ich in AWS Lambda viele Beispielprogramme gefunden, die node.js verwenden, aber ich konnte keine Python-Beispiele finden ... Ich bin gut in Python, daher möchte ich Python-Code schreiben.
Machen Sie einen WEB-Chat. Wenn Sie eine Verbindung zur Webseite herstellen und eine Nachricht schreiben, wird die Nachricht in Echtzeit an alle mit dieser Seite verbundenen Terminals (mit einer WebSocket-Sitzung) zu diesem Zeitpunkt übermittelt.
Es wird durch die Kombination von API Gateway, Lambda und DynamoDB erstellt, die typische Elemente von AWS ohne Server sind. Die zu veröffentlichende Webseite funktioniert nur durch Platzieren der HTML-Datei auf dem lokalen PC, oder sie funktioniert auch dann, wenn sie leicht durch Platzieren im statischen Hosting von S3 veröffentlicht werden kann.
Wählen Sie WebSocket aus, um ein neues API-Gateway zu erstellen.
Die Routenauswahlformel wird hier auf "$ request.body.action" gesetzt. Sie können dies später ändern.
Erstellen Sie die Route beim Verbinden (Verbinden), die Route beim Trennen (Trennen) und die Route beim Senden einer Nachricht (sendMessage) nacheinander.
Vorher muss ich jedoch eine DynamoDB- und eine IAM-Rolle erstellen.
Ich habe noch keine Routen erstellt, aber ich werde sie bereitstellen und eine Bühne erstellen.
Wenn es blau gelöscht wird, wird eine eindeutige Zeichenfolge eingegeben. Diese eindeutige Zeichenfolge wird beim nächsten Erstellen einer IAM-Rolle verwendet.
Fügen Sie zunächst "AWSLambdaBasicExecutionRole" hinzu, um Lambda auszuführen, und "AmazonDynamoDBFullAccess", um DynamoDB auszuführen. * Es muss kein Vollzugriff sein, aber es ist einfach.
Legen Sie danach die folgende Inline-Richtlinie fest. Sie können jetzt von Lambda aus auf die API Gatteway zugreifen.
Inline-Richtlinie
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"execute-api:ManageConnections"
],
"Resource": [
"arn:aws:execute-api:ap-northeast-1:<Mieterausweis hier>:<Schreiben Sie die eindeutige Zeichenfolge von API Gateway, die Sie zuvor hier festgelegt haben.>/*"
],
"Effect": "Allow"
}
]
}
Versuchen Sie im Bild der obigen Rolle, die blau gelöscht wird, die eindeutige Zeichenfolge festzulegen, die bei der ersten Bereitstellung von API Gateway angezeigt wurde.
Sollte der Primärschlüssel die Zeichenfolge "id" sein?
Erstellen Sie ein neues Lambda / Python 3.8. Legen Sie die zuvor verwendete IAM-Rolle fest. Das Programm ist einfach, da nur zwei Zeilen wirksam sind, ohne das abnormale System zu berücksichtigen. (Eigentlich sollte es unter Berücksichtigung des abnormalen Systems gemacht werden.) Sie müssen lediglich die verbundene Verbindungs-ID abrufen und bei DynamoDB registrieren.
ac19_onConnect/lambda_function.py
import json
import os
import boto3
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table(os.environ['CONNECTION_TABLE'])
def lambda_handler(event, context):
connection_id = event.get('requestContext',{}).get('connectionId')
result = connections.put_item(Item={ 'id': connection_id })
return { 'statusCode': 200,'body': 'ok' }
Legen Sie den Namen der zuvor in der Lambda-Umgebungsvariablen "CONNECTION_TABLE" erstellten DynamoDB fest. Die Timeout-Zeit sollte 3 Sekunden betragen, aber ich habe sie auf ungefähr 1 Minute eingestellt.
Integrieren Sie das obige Lambda "ac19_onConnect" in das zuvor erstellte API-Gateway-Verbindungsstammverzeichnis.
Die Vorgehensweise ist dieselbe, wenn die unten beschriebenen Root- und sendMessage-Roots in Lambda integriert werden. Vergessen Sie nicht, die Bühne nach ihrer Integration bereitzustellen.
Gehen Sie genauso vor wie bei der Verbindungsroute, erstellen Sie zuerst ein Lambda-Programm und integrieren Sie es in die API Gateway-Trennungsroute. Wenn Sie nicht an Anomalien denken, ist das Programm einfach. Rufen Sie einfach die getrennte Verbindungs-ID ab und entfernen Sie sie aus DynamoDB. Andere Einstellungen von Lambda (Rolle, Zeitlimit, Umgebungsvariablen) sind dieselben wie im vorherigen onConnect-Programm.
ac19_onDisconnect/lambda_function.py
import json
import os
import logging
import boto3
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table(os.environ['CONNECTION_TABLE'])
def lambda_handler(event, context):
connection_id = event.get('requestContext',{}).get('connectionId')
result = connections.delete_item(Key={ 'id': connection_id })
return { 'statusCode': 200, 'body': 'ok' }
Nur sendMessage hat ein paar Zeilen, aber das ist einfach. Wenn eine sendMessage empfangen wird, wird die Nachricht nur an jede in DynamoDB registrierte Verbindung gesendet. Befolgen Sie die gleichen Schritte wie zuvor, erstellen Sie zuerst ein Lambda-Programm, erstellen Sie eine sendMessage-Route in API Gateway und integrieren Sie sie in diese Route. Vergessen Sie dann nicht, API Geteway auf der Bühne bereitzustellen. Die anderen Einstellungen von Lambda (Rolle, Zeitlimit, Umgebungsvariablen) sind dieselben wie bei den beiden vorherigen Lambda.
ac19_sendMessage/lambda_function.py
import json
import os
import sys
import logging
import boto3
import botocore
dynamodb = boto3.resource('dynamodb')
connections = dynamodb.Table(os.environ['CONNECTION_TABLE'])
def lambda_handler(event, context):
post_data = json.loads(event.get('body', '{}')).get('data')
print(post_data)
domain_name = event.get('requestContext',{}).get('domainName')
stage = event.get('requestContext',{}).get('stage')
items = connections.scan(ProjectionExpression='id').get('Items')
if items is None:
return { 'statusCode': 500,'body': 'something went wrong' }
apigw_management = boto3.client('apigatewaymanagementapi',
endpoint_url=F"https://{domain_name}/{stage}")
for item in items:
try:
print(item)
_ = apigw_management.post_to_connection(ConnectionId=item['id'],
Data=post_data)
except:
pass
return { 'statusCode': 200,'body': 'ok' }
Schreiben Sie unter "wss: //" im Programm die eindeutige Zeichenfolge von API Gateway, die Sie zuvor festgelegt haben. Dieser HTML-Code kann auch dann ausgeführt werden, wenn er lokal auf dem PC platziert oder auf dem statischen Hosting von AWS S3 veröffentlicht wird.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test-Chat "Web Socket"!</title>
</head>
<body>
<H3>Test-Chat "Web Socket"!</H3>
<input id="input" type="text" />
<button onclick="send()">Senden</button>
<pre id="output"></pre>
<script>
var input = document.getElementById('input');
var output = document.getElementById('output');
var socket = new WebSocket("wss://<Schreiben Sie die eindeutige Zeichenfolge von API Gateway, die Sie zuvor hier festgelegt haben.>.execute-api.ap-northeast-1.amazonaws.com/v01");
socket.onopen = function() {
output.innerHTML += "Ich konnte mich verbinden!\n";
};
socket.onmessage = function(e) {
output.innerHTML += "Empfangen:" + e.data + "\n";
};
function send() {
socket.send(JSON.stringify(
{
"action":"sendMessage",
"data": input.value
}
));
input.value = "";
};
</script>
</body>
</html>
In Ordung! Dies ist abgeschlossen! Lass es uns versuchen!
Ich habe es hauptsächlich beim Betrachten der AWS-Seite gemacht. https://aws.amazon.com/jp/blogs/news/announcing-websocket-apis-in-amazon-api-gateway/
Jetzt, da ich ein WebSocket ohne AWS-Server einrichten kann, freue ich mich, verschiedene Dinge machen zu können. Dann Tag 3 von NTT Technocross Adventskalender 2019 Bitte genießen Sie weiterhin 5bc108bdf5068ef7be2f)!
Recommended Posts