У меня есть развернутый AWS шлюз API веб-сокета, интегрированный в лямбда-функцию AWS, с базовым сценарием использования приложения чата между клиентами. В настоящее время клиенты подключаются к веб-сокету с помощью clientid и отправляют сообщение в функцию Lambda в виде json объектного API.
Lambda просто маршрутизирует полученное сообщение назначенному клиенту, что прекрасно работает для отправка строковых сообщений, однако я хочу отправлять видео в реальном времени от одного клиента к другому с помощью той же службы, поэтому я попытался кодировать видеокадры в строки base64 и отправить через API. Я много пытался отправить живое видео, но я не могу ничего получить на другом клиенте.
Ниже приводится развернутая функция Lambda:
import json
import boto3
import botocore
from datetime import datetime
from aws_requests_auth.aws_auth import AWSRequestsAuth
import requests
from boto3.dynamodb.conditions import Key, Attr
from decimal import Decimal
import os
def applambda(event, context):
connectionId=event["requestContext"]["connectionId"]
body=json.loads(event["body"])
ReceiverID=body["ReceiverID"]
Msg=body["Msg"]
MessageDateTime=str(datetime.now().timestamp())
dynamoConnections=boto3.resource('dynamodb').Table("OnlineConnection")
resultU=dynamoConnections.scan(FilterExpression=Key('ClientID').eq(ReceiverID))
if resultU["Items"] is not None and len(resultU["Items"])==1:
ReceiverConnectionID=resultU["Items"][0]["token"]
resultX=dynamoConnections.scan(FilterExpression=Key("token").eq(connectionId))
if resultX["Items"] is not None and len(resultX["Items"])==1:
SenderID=resultX["Items"][0]["ClientID"]
jsonObjtoSend={"MessageID":MessageDateTime,"Message":Msg,"SenderID":SenderID}
sendDirectMessage(ReceiverConnectionID,jsonObjtoSend)
return {"statusCode":200,"body":"Message Delivered"}
else:
return {"statusCode":200,"body":"Error Occurred"}
else:
return {"statusCode":200,"body":"User not Online"}
def sendDirectMessage(token, jsonobj):
access_key=os.environ['access_key']
secret_key=os.environ['secret_key']
auth=AWSRequestsAuth(aws_access_key=access_key,
aws_secret_access_key=secret_key,aws_host='<ws host>-east-1.amazonaws.com',
aws_region='us-east-1',aws_service='execute-api'
)
url='<AWS http url>'+token.replace("=","")+"%3D"
req=requests.post(url,auth=auth,data=str(jsonobj))
print(req.text)
Ниже указан мой client_stream .py файл, который передает данные по API,
import json
import pprint
import base64
import cv2
import websocket
from websocket import create_connection
websocket.enableTrace(True)
ws = create_connection('<ws host wih client query>')
camera = cv2.VideoCapture(0)
str_obj = {
"Msg":"",
"ReceiverID":"shd",
"action":"sendmsg"
}
while True:
try:
grabbed, frame = camera.read() # grab the current frame
frame = cv2.resize(frame, (640, 480)) # resize the frame
encoded, buffer = cv2.imencode('.jpg', frame)
buffer = buffer.tostring()
jpg_as_text = base64.b64encode(buffer)
str_obj["Msg"] = str(jpg_as_text)
ws.send(json.dumps(str_obj))
except KeyboardInterrupt:
# print(jpg_as_text)
camera.release()
cv2.destroyAllWindows()
break
Ниже приведен мой файл client_viewer.py, который получает сообщение от Lambda:
import json
import pprint
import base64
import numpy as np
import cv2
import websocket
from websocket import create_connection
websocket.enableTrace(True)
ws = create_connection('<ws host wih client query>')
print("Connected")
while True:
try:
received = ws.recv()
#print(received)
if received is not None:
received = eval(received)
frame = received['Message']
img = base64.b64decode(frame)
npimg = np.fromstring(img, dtype=np.uint8)
source = cv2.imdecode(npimg, 1)
cv2.imshow("Stream", source)
cv2.waitKey(1)
except KeyboardInterrupt:
cv2.destroyAllWindows()
break
Я вполне могу отправить любое сообщение другим клиентам через API,
{"Msg":"<message>", "ReceiverID":"shd", "action":"sendmsg"}