피아노 수업 - MuleSoft 독립 WebSocket 어플리케이션
맨날 API 날이에요.
만약 당신이 매일 피아노를 연습한다면, 당신의 연주를 녹음하고 선생님과 공유하고 싶지만, 휴대전화나 PC에 저장하고 싶지 않을 수도 있습니다.
이것이 바로 API의 용무지다!
이'피아노 수업'은 동영상을 포착하고 웹소켓이 연결된 무어소프트 API를 통해 AWS S3 버킷으로 데이터를 전송하는 앱이다.
그리고
이 프로그램은 완전히 MuleSoft가 실행될 때 실행됩니다. 네, 포함되어 있습니다.CloudHub worker 1명은 웹 서버,api 서버, 데이터베이스 서버 역할을 합니다.다른 서버는 필요 없어요!!
리소스
Demo@CloudHub
Demo@CloudHub
github
건축과 설계
건축하다
이 응용 프로그램은 두 가지 서비스인 "MuleSoft CloudHub"와 "AWS S3"을 사용합니다.AWS S3는 파일 스토리지만 제공합니다.기타 모든 기능은 MuleSoft CloudHub에서 실행할 때 제공됩니다.
무레스포드
MuleSoft가 실행될 때 응용 프로그램은 주로 4개의 흐름 설정 파일로 구성되어 있는데 그것이 바로 웹,api, 데이터베이스와 데이터이다.웹과api는 "HTTP 탐지기"를 포함하여 사용자 장치에 함수를 공개하는 데 사용되며, 다른 것은 내부 논리의 집합일 뿐입니다.
같은 호스트 이름과 포트에서 온 모든 포트를 제공함으로써 우리는'cookies'('SameSite=Strict'사용)를 안전하게 사용하여'세션'기능(https://'접근과'wss://'접근 사이까지!)을 실현할 수 있습니다.
WebFlow는 React 프레임워크에서 지원하는 SPA(한 페이지 응용 프로그램) 리소스를 제공합니다.이 SPA에는 HTML 파일과 자바스크립트 파일 두 개의 자원만 포함됩니다.파일이 두 개밖에 없기 때문에, MuleSoft가 실행될 때 파일 구성 요소와 HTTP 탐지기를 사용하여 모든 HTML 파일과 자바스크립트 파일의 내용을 보내서 특정한 GET 호출에 응답할 수 있습니다.
AWS S3
AWS S3는'다부분 업로드'와'객체 사전 서명 URL'이라는 두 가지 유용한 기능을 제공합니다.'다부분 업로드'는 응용 프로그램 자체가 5MB를 넘을 필요가 없기 때문에 이런 응용 프로그램에 매우 유용하다.응용 프로그램은 최소한 5MB의 데이터 블록을 업로드하고 ETAg를 업로드가 끝날 때까지 되돌려줍니다.객체 사전 서명 URL은 응용 프로그램에서 비디오를 재생할 수 있도록 저장된 데이터 파일을 다운로드합니다.
클라이언트 응용 프로그램에서 호출할 수 있지만, 이것은 HTMT/js에 AWS 증빙서류가 노출되는 심각한 안전 위험을 초래할 수 있다.이것이 바로 이 클라이언트 프로그램이 같은 실행할 때 (호스트 이름/포트) MuleSoft API를 호출하고 쿠키에서 JWT 영패를 공유하는 이유입니다. API는 AWS 인증서를 사용하여 AWS S3 API를 호출합니다.
고려 요소
모바일 브라우저(iOS Safari)
이 응용 프로그램은 iOS(Safari)에서 실행할 수 없습니다.현재 iOS Safari는 '미디어 레코더' 를 지원하지 않는다. (실험적인 기능인 '미디어 레코더' 를 사용하면 작동할 수 있을 것 같지만, 버퍼는 지원하지 않는다.)미디어 흐름을 직접 처리해야 돼...
데이터베이스 및 객체 저장소
이 프로그램은 ObjectStore를 데이터베이스로 사용하지만 대상만 저장하고 TTL 등 제한이 있어 실제 데이터베이스가 아닌 생산 데이터베이스로 사용하기에 적합하지 않다.캐시와 임시 메모리를 사용하는 데는 대상 저장이 좋지만 사무적 데이터 저장은 안 된다.
네트워크 서버...
좋아요.현대화된 웹 서버 (CA와 서명한 인증서) 가 있습니다. 좋습니다.
설계
유동
웹(skd 피아노 수업 웹.xml)
이 프로세스는 SPA 리소스 및 WebSocket 엔드포인트를 제공합니다.
/js/login.index“,/js/login/index“,/js/login/index“,/js/login.html“,/js/login/index“,/js/login/index“,/js/login.html“,/js/login/index“,/js/login/index“,/js/login/index“,/js/login.html“,/js.
사용자 이름/비밀번호가 조건에 부합될 때만 목적지'/'를 사용하여'/login'응답 302를 발표합니다.
wss 프로토콜이 있는 '/ws/data' 는 웹 소켓 구성 요소가 있는 웹 소켓 서버로 충당합니다.https://docs.mulesoft.com/websockets-connector/1.0/websockets-connector-cloudhub에 따르면 공유 부하 균형기(SLB)는 ws/wss 데이터를 전파하지 않는다(호스트 이름과 포트가https와 완전히 같아도!).전용 로드 밸런서(DLB)가 없기 때문에 프레젠테이션에서 "mule worker"호스트 이름과 8082 포트를 사용해야 합니다
api(skd piano lesson.xml)
이 프로세스는 데이터베이스 액세스, AWS S3 액세스와 같은 서버측 기능을 제공합니다.이것은 API 키트를 사용하여 라우터 이전에 세션(cookie의 JWT)이 항상 검증됩니다.'웹과 API 서버'가 있어요. 좋아요!
데이터베이스(skd piano lessiondb.xml)
이 유통 과류 인용 구성 요소는 웹과api 흐름 내부에서 호출된 데이터베이스 접근을 제공합니다.이 기능은 Mongo DB 서버나 유사한 것에 공개할 수 있지만, 이 프로그램은 '대상 저장' 기능의 제한을 요구합니다. (생산에 사용하지 마십시오.)
데이터(skd piano lesson data.xml)
이 흐름은 웹 흐름에서 호출되는 웹소켓 데이터 처리 과정을 제공합니다.WebSocket 클라이언트의 첫 번째 메시지는 Id 등의 속성을 기록하는 것이다. 이 과정은'WebSocket 키(sec WebSocket key header value)'와'기록 Id'의 맵을 대상 저장소에 저장하여 두 번째 메시지(이진법 영상 데이터)가 WebSocket 키를 통해 기록 Id와 링크할 수 있도록 한다.
init(skd 피아노 수업 init.xml)
이 흐름은 초기 데이터(관리자 자격 증명)를 만들기 위해 스케줄러만 표시됩니다.런타임 관리자에서 이 스케줄러를 실행하면 초기 데이터를 불러올 수 있습니다.
구현
세션 및 검증
MuleSoft runtime는 진정한 웹 서버가 아니기 때문에, 나는 어쩔 수 없이 간단한 세션 기능을 실현해야 하지만, 이것은 듣기에 그렇게 어렵지 않다.키는 JWT 및 Set Cookie header 입니다.
JWT(Json WebToken)는 양측 간에 전송할 성명을 나타내는 빈틈없는 URL 보안 방식이다.따라서 비밀 문자열로 사용자 id를 암호화하고 로그인 과정이 끝날 때 클라이언트의 브라우저 쿠키에 암호화 문자열을 설정합니다.
MuleSoft는 암호화 기능을 제공하지만 암호화를 명확하게 처리하기 위해 "com.auth0.jwt.jwt"패키지(groupId="com.auth0",artifactId="javajwt")가 있는 자바를 사용했습니다.이것은 매우 간단하다.
문자열을 클라이언트의 쿠키로 설정하려면 로그인 요청 응답의'set 쿠키'헤더에 다음 문자열을 설정하십시오(성공적으로 로그인하면 사용자를'/'로 안내하기 때문에 HTTP 탐지기 응답에'Location'헤더와 상태 302를 설정합니다.
세션을 검증하려면 "쿠키"요청 헤더를 검사하고 세션 id 문자열 형식을 검증하며 JWT를 검증합니다.
이런 검증 논리는 API 프로세스뿐만 아니라 정적 자원 접근도 설정할 수 있다. 예를 들어'/index.html'과 웹소켓 서버 프로세스는 완전히 같은 호스트 이름과 포트 번호를 사용하기 때문이다!
그물주머니
처음에 나는'socket.io'https://socket.io/docs/v3/index.html를 사용하여 노드가 있는 웹소켓 클라이언트를 실현했다.js, 그러나 놀랍고 불행하게도, 이것은 MuleSoft WebSocket 구성 요소를 호환하지 않는 것 같습니다.
무슨 콘센트?목위일무
Socket.IO is NOT a WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds additional metadata to each packet. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a plain WebSocket server either.
https://socket.io/docs/v3/index.html
좋아요.그런 다음 브라우저 기본 WebSocket API를 사용해야 합니다."socket.io"는 바이너리 데이터와 속성 같은 여러 가지 데이터를 동시에 보낼 수 있기 때문에 매우 유용하다.
const socket = io('ws://localhost:3000');
socket.on('connect', () => {
// either with send()
socket.send('Hello!');
// or with emit() and custom event names
socket.emit('salutations', 'Hello!', { 'mr': 'john' }, Uint8Array.from([1, 2, 3, 4]));
});
// handle the event sent with socket.emit()
socket.on('greetings', (elem1, elem2, elem3) => {
console.log(elem1, elem2, elem3);
});
https://socket.io/docs/v3/index.html 그러나 네이티브 웹소켓 API에서는 이러한'전송'을 허용하지 않습니다.내 HTTP 헤더를 사용하려고 했지만, 원본 웹 소켓 API나 Mule Soft 웹 소켓 구성 요소에서는 헤더에 접근할 수 없습니다."녹음 id"를 보내야 합니다. 이것은 이전에 API가 "/API/start"를 호출해서 생성한 것과 서로 연결된 이진 데이터입니다.
그리고 'recording id' 를 첫 번째 웹소켓 메시지로 보내고, 이진 데이터를 다음 메시지로 보내기로 결정했습니다.서버(MuleSoft)에서 워크로드를 저장하기 위해 미디어타입 및 스토리지 매핑을 확인합니다.레코드 id는 미디어Type "text/plain"과 함께 전송되며 바이너리 데이터는 "application/octet stream"과 함께 전송됩니다.'텍스트/계획' 데이터를 받으면'atteributes.headers.sec 웹소켓 키 '와 유효 부하 (기록 id) 의 맵을 저장합니다.'application/octet stream' 이라면 sec 웹소켓 키가 대상에 저장되어 있다고 가정하고 id 녹음과 관련된 정보를 얻을 수 있습니다.
이 매핑은 바이너리 데이터를 5MB까지 버퍼링하는 데도 사용됩니다.
이진 데이터 처리
AWS S3 멀티 섹션은 업로드가 편리하지만, "각 섹션의 최소 크기는 5MB(마지막 섹션 제외)여야 한다"는 제한이 있습니다.이 "5MB"는 MuleSoft가 실행될 때와 브라우저의 서버입니다...그러나 개체 저장소는 10MB의 기록을 처리할 수 있다.
이 클라이언트 프로그램은 10초마다 이진 데이터를 보내고 서버 사이드(Mule Soft)는 이를 Object Store에 저장하고 sec 웹소켓 키를 키로 사용합니다.이때 새 바이너리 데이터와 저장된 바이너리 데이터가 연결된 다음 다시 저장됩니다. (만약 <5MB)
연결은 DataWeave를 사용하는 방법을 찾을 수 없기 때문에 사용자 정의 Java 클래스 "Binary Utils"에서 처리됩니다.자바 매개 변수/되돌림 중, 'Binary' 형식은'byte [] '로 변환되기 때문에, Byte Array Output Stream만 연결하면 간단하고 쉽습니다.
만약 미디어타입이 '응용 프로그램/java' 라면 사이즈 Of (이진 데이터) 는 작동할 수 있습니다. (실제로는'byte [] '이기 때문입니다.)그러나 왠지 모르게 '응용 프로그램/8바이트 흐름' 은 안 된다.
API용 RAML
#%RAML 1.0
title: skd-piano-lesson
types:
Error:
example:
{message : "Unknown error"}
properties:
message:
type: string
description: error message
User: !include schemas/user-dataType.raml
Piece: !include schemas/piece-dataType.raml
Recording: !include schemas/recording-dataType.raml
Playlist: !include schemas/playlist-dataType.raml
/me:
description: Handle login user information
get:
displayName: Get login user information
responses:
200:
body:
application/json:
type: User
401:
description: Unauthorized error
body:
application/json:
type: Error
/user:
post:
displayName: Upsert a User
description: if matched Id is found, this upserts the given record. if not, inserts. "password" has to be given as "Non-Encrypted" string.
body:
application/json:
type: User
responses:
200:
body:
application/json:
type: User
401:
description: Unauthorized error
body:
application/json:
type: Error
/{user_id}:
uriParameters:
user_id:
displayName: User Id
type: string
description: the Id of the User you query
get:
displayName: Get a User
description: Reterns a User if Id matched. "password" is given as "Encrypted" string.
responses:
200:
body:
application/json:
type: User
401:
description: Unauthorized error
body:
application/json:
type: Error
/pieces:
get:
displayName: Get all Pieces of the user
queryParameters:
inlist:
description: if true, this returns all "inlist=true" pieces of the user. if false, "inlist=false"
type: boolean
default: true
responses:
200:
body:
application/json:
type: Piece[]
401:
description: Unauthorized error
body:
application/json:
type: Error
/piece:
post:
displayName: Upsert a Piece
description: if matched Id is found, this upserts the given record. if not, inserts.
body:
application/json:
type: Piece
responses:
200:
body:
application/json:
type: Piece
401:
description: Unauthorized error
body:
application/json:
type: Error
/playlist:
get:
displayName: Get a playlist
queryParameters:
datestring:
description: target datestring (YYYY-MM-DD format
type: string
required: true
piece_id:
description: if specified, this returns a list with only the piece
type: string
required: false
responses:
200:
body:
application/json:
type: Playlist
401:
description: Unauthorized error
body:
application/json:
type: Error
/composers:
get:
displayName: Get a list of composers the user has
responses:
200:
body:
application/json:
type: array
items:
properties:
composer:
type: string
description: name of the composer
401:
description: Unauthorized error
body:
application/json:
type: Error
/recording:
/{id}:
uriParameters:
id:
type: string
displayName: Recording Id
description: Id of the recording you query
get:
displayName: Get a recording and the signed url
responses:
200:
body:
application/json:
properties:
recording:
displayName: the recording info
type: Recording
signedUrl:
displayName: Signed URL for AWS S3
type: string
401:
description: Unauthorized error
body:
application/json:
type: Error
/start:
post:
displayName: start recording
description: start recording by creating a recording record and preparing multi-part upload
body:
application/json:
properties:
piece_id:
displayName: Piece Id
description: Id of the piece for the recording
type: string
required: true
datestring:
displayName: Date String (YYYY-MM-DD)
description: Lesson date in YYYY-MM-DD format
type: string
required: true
responses:
200:
body:
application/json:
type: Recording
401:
description: Unauthorized error
body:
application/json:
type: Error
/stop:
post:
displayName: stop recording
description: stop recording by completing multi-part upload
body:
application/json:
properties:
recording_id:
displayName: Recording Id
description: Id of the recording to stop
type: string
required: true
responses:
200:
body:
application/json:
type: object
properties:
Location:
description: URL of the recording file
type: string
Bucket:
description: bucket name to be stored
type: string
Key:
description: Key of the recording file
type: string
ETag:
description: ETag for the upload
type: string
401:
description: Unauthorized error
body:
application/json:
type: Error
Reference
이 문제에 관하여(피아노 수업 - MuleSoft 독립 WebSocket 어플리케이션), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ssakoda/piano-lesson-mulesoft-self-contained-websocket-application-17ha텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)