Lassen Sie uns einen Web-Chat mit WebSocket mit AWS serverless (Python) durchführen!

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 240_news012.jpg

... 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.

Was zu machen

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. qiita作るもの.png

Systemkonfiguration

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.

qiita作るもの.png

Codierung

1. Bereiten Sie zuerst das API-Gateway vor!

1-1. Erstellen Sie ein neues API-Gateway für "Web Socket".

Wählen Sie WebSocket aus, um ein neues API-Gateway zu erstellen. キャプチャ.PNG

Die Routenauswahlformel wird hier auf "$ request.body.action" gesetzt. Sie können dies später ändern.

1-2. Ich mache von hier aus nacheinander Routen

Erstellen Sie die Route beim Verbinden (Verbinden), die Route beim Trennen (Trennen) und die Route beim Senden einer Nachricht (sendMessage) nacheinander. キャプチャ.PNG

Vorher muss ich jedoch eine DynamoDB- und eine IAM-Rolle erstellen.

1-3. Bereitstellen und Erstellen einer Bühne

Ich habe noch keine Routen erstellt, aber ich werde sie bereitstellen und eine Bühne erstellen. キャプチャ.PNG

Wenn es blau gelöscht wird, wird eine eindeutige Zeichenfolge eingegeben. Diese eindeutige Zeichenfolge wird beim nächsten Erstellen einer IAM-Rolle verwendet.

2. Erstellen Sie eine IAM-Rolle für Lambda

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. キャプチャ.PNG

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.

3. Erstellen Sie eine Tabelle (DynamoDB), die Verbindungsinformationen verwaltet

Sollte der Primärschlüssel die Zeichenfolge "id" sein? キャプチャ.PNG

4. Erstellen Sie beim Verbinden eine Verbindung

4-1. Machen Sie Lambda

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.

4-2. Integrieren Sie API Gateway und Lambda

Integrieren Sie das obige Lambda "ac19_onConnect" in das zuvor erstellte API-Gateway-Verbindungsstammverzeichnis. キャプチャ.PNG

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.

5. Erstellen Sie beim Trennen eine Wurzel (Trennen)

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' }

6. Erstellen Sie eine Route (sendMessage), wenn eine sendMessage empfangen wird

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' }

7. Erstellen Sie eine HTML-Webseite

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! qiita作るもの.png

Referenz

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/

abschließend

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

Lassen Sie uns einen Web-Chat mit WebSocket mit AWS serverless (Python) durchführen!
Erstellen Sie ein Webframework mit Python! (2)
[Chat De Tornado] Erstellen Sie einen Chat mit WebSocket in Tornado
Lassen Sie uns eine GUI mit Python erstellen.
Lassen Sie uns ein Diagramm mit Python erstellen! !!
Lassen Sie uns mit Python einen Web-Socket-Client erstellen. (Zugriffstoken-Authentifizierung)
Lassen Sie uns mit Python ein Shiritori-Spiel machen
Lassen Sie uns mit Python langsam sprechen
Machen wir einen Twitter-Bot mit Python!
Ersetzen wir UWSC durch Python (5) Machen wir einen Roboter
Lassen Sie uns mit SWIG ein Modul für Python erstellen
[Lass uns mit Python spielen] Ein Haushaltsbuch erstellen
Versuchen Sie, ein einfaches Spiel mit Python 3 und iPhone zu erstellen
Machen Sie eine Lotterie mit Python
[Super einfach] Machen wir einen LINE BOT mit Python.
Machen wir einen Blockbruch mit wxPython
Erstellen Sie ein Empfehlungssystem mit Python
Machen wir mit xCAT einen Spacon
[AWS Hands-on] Erstellen wir einen Promi-Identifikationsdienst mit einer serverlosen Architektur!
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 2 erstellen
Lassen Sie uns eine WEB-Anwendung für das Telefonbuch mit Flasche Teil 3 erstellen
Erstellen Sie mit Python + Django + AWS eine Scraping-App und wechseln Sie Jobs
Ich habe einen Pokerspielserver Chat-Holdem mit Websocket mit Python erstellt
[AWS] Verwenden von INI-Dateien mit Lambda [Python]
Erstellen wir mit Python eine kostenlose Gruppe
Dämonisieren Sie eine Python-Webanwendung mit Supervisor
Lassen Sie uns mit PLY 1 eine einfache Sprache erstellen
[Python] Eine schnelle Webanwendung mit Bottle!
[Python] Lassen Sie uns matplotlib mit Japanisch kompatibel machen
Lassen Sie uns mit flask-babel eine mehrsprachige Site erstellen
Führen Sie eine Python-Webanwendung mit Docker aus
Machen wir mit Pylearn 2 eine dreiäugige KI
Lassen Sie uns eine Kombinationsberechnung mit Python durchführen
Erstellen Sie eine Desktop-App mit Python mit Electron
Berühren Sie AWS mit Serverless Framework und Python
Erstellen wir eine Chat-Funktion mit Vue.js + AWS Lambda + Dynamo DB [AWS-Einstellungen]
[Ev3dev] Lassen Sie uns ein Fernsteuerungsprogramm von Python mit dem RPyC-Protokoll erstellen
[Streamlit] Ich hasse JavaScript, deshalb erstelle ich eine Webanwendung nur mit Python
Lassen Sie uns eine 3D-Animation nur mit Python erstellen, ohne Blender zu verwenden! [FBX SDK Python]
Ich habe versucht, einen URL-Verkürzungsdienst mit AWS CDK serverlos zu machen
Ich möchte eine Webanwendung mit React und Python Flask erstellen
Implementieren Sie eine einfache Anwendung mit Python Full Scratch ohne Verwendung eines Webframeworks.
Machen Sie Twitter Trend Bot mit Heroku + Python
Ich möchte ein Spiel mit Python machen
Starten Sie mit Docker einen einfachen Python-Webserver
Erstellen Sie eine Webmap mit Python und GDAL
Starten Sie einen Webserver mit Python und Flask
Web Scraping mit Python (Wettervorhersage)
Web Scraping mit Python (Aktienkurs)
Extrahieren Sie mit Python Daten von einer Webseite
Lassen Sie uns mit Flask eine Webanwendung zur Konvertierung von A nach B erstellen! Von Grund auf neu ...
WEB Scraping mit Python und versuchen, aus Bewertungen eine Wortwolke zu machen
Wenn Sie einen Discord-Bot mit Python erstellen möchten, verwenden wir ein Framework
Kombinieren Sie sich wiederholende Zeichenfolgen mit regulären Python-Ausdrücken zu einer.
Lassen Sie uns ein Befehls-Standby-Tool mit Python erstellen
(Python) Versuchen Sie, eine Webanwendung mit Django zu entwickeln
[Übung] Erstellen Sie eine Watson-App mit Python! # 2 [Übersetzungsfunktion]