연습 – SignalR Service를 사용하여 웹 애플리케이션에서 자동 업데이트 사용

완료됨

이 프로토타입에 SignalR을 추가하려면 다음을 만들어야 합니다.

  • Azure SignalR 리소스
  • SignalR을 지원하는 몇 가지 새로운 함수
  • SignalR을 지원하도록 클라이언트 업데이트

SignalR 리소스 만들기

Azure SignalR 리소스를 만들어야 합니다.

  1. SignalR 리소스를 만들려면 터미널로 돌아갑니다.

  2. 리소스를 만들려면 setup-resources 하위 디렉터리로 이동합니다.

    cd stock-prototype/setup-resources && bash create-signalr-resources.sh & cd ..
    
  3. SignalR 리소스에 대한 연결 문자열을 복사합니다. 서버 코드를 업데이트하려면 이 정보가 필요합니다.

    리소스 종류 환경 변수
    Azure SignalR 참조: SIGNALR_CONNECTION_STRING

서버 구성 환경 변수 업데이트

./start/server/local.settings.json에서 터미널에 나열된 값을 사용하여 SIGNALR_CONNECTION_STRING이라는 Values 개체에 변수를 추가하고 파일을 저장합니다.

signalr-open-connection 함수 만들기

웹 클라이언트에서 SignalR 클라이언트 SDK를 사용하여 서버에 대한 연결을 설정합니다. SDK는 서비스에 연결하기 위해 signalr-open-connection이라는 함수를 통해 연결을 검색합니다.

  1. F1 키를 눌러 Visual Studio Code 명령 팔레트를 엽니다.

  2. Azure Functions: Create Function 명령을 찾아 선택합니다.

  3. 기본값 설정을 선택한 다음 시작/서버를 선택하여 함수 앱의 위치를 설정합니다.

  4. VS Code와 함께 사용할 프로젝트를 초기화하려고 하나요?라는 메시지가 나타나면 를 선택합니다.

  5. 메시지가 표시되면 다음 정보를 제공합니다.

    이름
    템플릿 HTTP 트리거
    속성 signalr-open-connection

    이제 signalr-open-connection.ts라는 파일을 ./start/server/src/functions에서 사용할 수 있습니다.

  6. signalr-open-connection.ts를 열고 모든 내용을 다음 코드로 바꿉니다.

    import { app, input } from '@azure/functions';
    
    const inputSignalR = input.generic({
        type: 'signalRConnectionInfo',
        name: 'connectionInfo',
        hubName: 'default',
        connectionStringSetting: 'SIGNALR_CONNECTION_STRING',
    });
    
    app.http('open-signalr-connection', {
        authLevel: 'anonymous',
        handler: (request, context) => {
            return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
        },
        route: 'negotiate',
        extraInputs: [inputSignalR]
    });
    

    SignalR 연결 정보는 함수에서 반환됩니다.

signalr-send-message 함수 만들기

  1. F1 키를 눌러 Visual Studio Code 명령 팔레트를 엽니다.

  2. Azure Functions: Create Function 명령을 찾아 선택합니다.

  3. 함수 앱의 위치를 시작/서버로 선택합니다.

  4. 메시지가 표시되면 다음 정보를 제공합니다.

    이름
    템플릿 {b>Azure Cosmos DB 트리거
    속성 signalr-send-message
    Cosmos DB 연결 문자열 COSMOSDB_CONNECTION_STRING
    모니터링할 데이터베이스 이름 stocksdb
    컬렉션 이름 stocks
    임대 컬렉션이 있는지 확인하고 자동으로 만들기 true

    Visual Studio Code에서 [탐색기] 창을 새로 고쳐 업데이트를 확인합니다. 이제 signalr-open-connection이라는 파일을 ./start/server/src/functions에서 사용할 수 있습니다.

  5. signalr-send-message.ts를 열고 모든 내용을 다음 코드로 바꿉니다.

    import { app, output, CosmosDBv4FunctionOptions, InvocationContext } from "@azure/functions";
    
    const goingOutToSignalR = output.generic({
        type: 'signalR',
        name: 'signalR',
        hubName: 'default',
        connectionStringSetting: 'SIGNALR_CONNECTION_STRING',
    });
    
    export async function dataToMessage(documents: unknown[], context: InvocationContext): Promise<void> {
    
        try {
    
            context.log(`Documents: ${JSON.stringify(documents)}`);
    
            documents.map(stock => {
                // @ts-ignore
                context.log(`Get price ${stock.symbol} ${stock.price}`);
                context.extraOutputs.set(goingOutToSignalR,
                    {
                        'target': 'updated',
                        'arguments': [stock]
                    });
            });
        } catch (error) {
            context.log(`Error: ${error}`);
        }
    }
    
    const options: CosmosDBv4FunctionOptions = {
        connection: 'COSMOSDB_CONNECTION_STRING',
        databaseName: 'stocksdb',
        containerName: 'stocks',
        createLeaseContainerIfNotExists: true,
        feedPollDelay: 500,
        handler: dataToMessage,
        extraOutputs: [goingOutToSignalR],
    };
    
    app.cosmosDB('send-signalr-messages', options);
    
  • 수신 데이터 정의: comingFromCosmosDB 개체는 변경 내용을 감시하기 위한 Cosmos DB 트리거를 정의합니다.
  • 발신 전송 정의: goingOutToSignalR 개체는 동일한 SignalR 연결을 정의합니다. HubName은 동일한 허브 default입니다.
  • 데이터를 전송 수단에 연결: dataToMessagestocks 테이블의 변경된 항목을 가져오고 동일한 허브 default를 사용하는 extraOutputs를 사용하여 SignalR을 통해 변경된 각 항목을 개별적으로 보냅니다.
  • 앱에 연결: app.CosmosDB는 바인딩을 함수 이름 send-signalr-messages에 연결합니다.

변경 내용을 커밋하고 GitHub에 푸시

  1. 터미널에서 변경 내용을 리포지토리에 커밋합니다.

    git add .
    git commit -m "Add SignalR functions"
    git push
    

signalr-send-message 함수 만들기

새 함수 코드를 게시할 수 있는 함수 앱 및 관련 리소스를 Azure에서 만듭니다.

  1. Azure Portal을 열어 새 함수 앱을 만듭니다.

  2. 다음 정보를 사용하여 리소스 만들기 기본 사항 탭을 완료합니다.

    속성
    Resource group 새 리소스 그룹 이름 stock-prototype을 만듭니다.
    함수 앱 이름 사용자의 이름을 api에 추가합니다. 예들 들어 api-jamie입니다.
    코드 또는 컨테이너 코드를 선택합니다.
    런타임 스택 Node.js를 선택합니다.
    버전 Node.js의 LTS 버전을 선택합니다.
    지역 가까운 지역을 선택합니다.
    운영 체제 Linux를 선택합니다.
    호스팅 사용량 플랜을 선택합니다.
  3. 다른 탭을 작성하지 않고 검토 + 만들기를 선택한 다음 만들기를 선택합니다. 배포가 완료될 때까지 기다린 후 계속합니다.

  4. 리소스로 이동을 선택하여 새 함수 앱을 엽니다.

GitHub 배포 구성

지속적인 배포를 사용하도록 설정하려면 새 함수 앱을 GitHub 리포지토리에 연결합니다. 프로덕션 환경에서는 코드 변경 내용을 프로덕션으로 교환하기 전에 스테이징 슬롯에 배포합니다.

  1. 새 함수 앱에 대한 Azure Portal 페이지의 왼쪽 메뉴에서 배포 센터를 선택합니다.

  2. GitHub원본를 선택합니다.

  3. 다음 정보를 사용하여 배포 구성을 완료합니다.

    속성
    조직 GitHub 계정을 선택합니다.
    리포지토리 mslearn-advocates.azure-functions-and-signalr을 검색하고 선택합니다.
    지점 main 분기를 선택합니다.
    워크플로 옵션 워크플로 추가...를 선택합니다.
    인증 유형 사용자가 할당한 ID를 선택합니다.
    구독 페이지 상단에 표시된 것과 동일한 구독을 선택합니다.
    ID 새로 만들기를 선택합니다.
  4. 섹션 상단에서 저장을 선택하여 설정을 저장합니다. 이렇게 하면 포크된 리포지토리에 새 워크플로 파일이 만들어집니다.

  5. 이 배포 구성은 리포지토리에 GitHub Actions 워크플로 파일을 만듭니다. 함수 앱에 대한 올바른 패키지 경로를 사용하려면 워크플로 파일을 업데이트해야 합니다.

GitHub 배포 워크플로 편집

  1. Visual Studio Code 터미널에서 포크(원본)에서 새 워크플로 파일을 풀다운합니다.

    git pull origin main
    

    이렇게 하면 워크플로 파일 경로가 `.github/workflows/main_RESOURCE_NAME.yml이고 RESOURCE_NAME이 Azure Functions 앱 이름인 .github에 새 폴더가 생성됩니다.

  2. 워크플로 파일을 엽니다.

  3. 파일 상단의 name 값을 Server로 변경합니다.

  4. 원본 리포지토리의 하위 디렉터리에 Azure Functions 앱이 있으므로 이를 반영하도록 작업 파일을 변경해야 합니다. env 섹션에서 패키지 경로를 사용하려면 PACKAGE_PATH라는 새 변수를 추가합니다.

    env:
      PACKAGE_PATH: 'start/server'
    
  5. Npm을 사용하여 프로젝트 종속성 해결 단계를 찾아 콘텐츠를 다음 YAML로 바꿔 패키지 하위 디렉터리 경로도 사용합니다. 중요한 변경 내용은 env.PACKAGE_PATH 변수를 포함하는 pushd 명령의 경로입니다.

    - name: 'Resolve Project Dependencies Using Npm'
      shell: bash
      run: |
        pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/${{ env.PACKAGE_PATH }}'
        npm install
        npm run build --if-present
        npm run test --if-present
        popd
    
  6. 패키지 하위 디렉터리 경로도 사용하려면 배포용 Zip 아티팩트 단계를 찾아 콘텐츠를 다음 YAML로 바꿉니다.

    - name: Upload artifact for deployment job
      uses: actions/upload-artifact@v3
      with:
        name: node-app
        path: release.zip
    

    Zip 파일은 리포지토리의 루트에 배치되므로 Zip 파일을 루트에 배치하려면 ../ 값이 필요합니다.

  7. 파일을 저장하고 변경 내용을 리포지토리에 커밋합니다.

    git add .
    git commit -m "Update deployment workflow to use package path"
    git push
    

    이 변경으로 인해 워크플로가 트리거됩니다. GitHub 포크의 Actions 섹션에서 워크플로를 볼 수 있습니다.

API 함수에 대한 환경 변수 구성

  1. Azure Portal에서 설정 -> 구성을 선택한 다음 새 애플리케이션 설정을 선택합니다.

  2. Cosmos DB 및 SignalR 연결 문자열에 대한 설정을 입력합니다. start/server 폴더의 local.settings.json에서 값을 찾을 수 있습니다.

    속성
    COSMOSDB_CONNECTION_STRING Cosmos DB 계정에 대한 연결 문자열입니다.
    SIGNALR_CONNECTION_STRING SignalR 계정에 대한 연결 문자열입니다.
  3. 저장을 선택하여 설정을 저장합니다.

API Functions 배포 테스트

  1. Azure Portal에서 개요를 선택하고 URL을 선택하여 브라우저에서 앱을 엽니다.
  2. URL을 복사합니다. 이는 단위 7에서 작업할 때 BACKEND_URL 값에 대한 클라이언트 .env 파일을 업데이트할 때 필요합니다.
  3. API 함수를 테스트하려면 브라우저에서 URL을 엽니다.
  4. 브라우저의 URL에 /api/getStocks를 추가하고 Enter 키를 누릅니다. 주식 데이터가 포함된 JSON 배열이 표시됩니다.

SignalR을 사용하여 주식을 반환하도록 서버 코드를 업데이트했으며 함수 앱에 배포했습니다. 다음으로 SignalR을 사용하여 업데이트를 수신하도록 클라이언트를 업데이트합니다.