다음을 통해 공유


작업 예약 및 브로드캐스트(.NET)

Azure IoT Hub를 사용하여 수백만 대의 디바이스를 업데이트하는 작업을 예약하고 추적합니다. 작업을 사용하여 다음을 수행합니다.

  • desired 속성 업데이트

  • tags 업데이트

  • 직접 메서드 호출

작업(job)은 이러한 작업(action) 중 하나를 래핑하고 디바이스 쌍 쿼리로 정의된 디바이스 집합에 대한 실행을 추적합니다. 예를 들어 백 엔드 앱은 작업(job)을 사용하여 10,000대 디바이스에 대해 디바이스를 재부팅하는 직접 메서드를 호출할 수 있습니다. 디바이스 쌍 쿼리로 디바이스 집합을 지정하고 향후 실행될 작업(job)을 예약합니다. 작업은 해당하는 각 디바이스에서 재부팅 직접 메서드를 수신 및 실행할 때 진행 상태를 추적합니다.

이러한 각 기능에 대한 자세한 내용은 다음을 참조하세요.

참고 항목

이 문서에서 설명하는 기능은 IoT Hub의 표준 계층에서만 사용할 수 있습니다. 기본 및 표준/무료 IoT Hub 계층에 대한 자세한 내용은 솔루션에 적합한 IoT Hub 계층 선택을 참조하세요.

이 문서에서는 두 개의 .NET(C#) 콘솔 앱을 만드는 방법을 보여 줍니다.

  • 백 엔드 앱에 의해 호출될 수 있는 LockDoor라는 직접 메서드를 구현하는 SimulateDeviceMethods라는 디바이스 앱을 만듭니다.

  • 두 개의 작업을 만드는 ScheduleJob이라는 백 엔드 앱을 만듭니다. 한 작업은 lockDoor 직접 메서드를 호출하고 다른 작업은 원하는 속성 업데이트를 여러 디바이스로 보냅니다.

참고 항목

디바이스 및 백 엔드 앱을 빌드하는 데 사용할 수 있는 SDK 도구에 대한 자세한 내용은 Azure IoT SDK를 참조하세요.

필수 조건

  • Visual Studio.

  • Azure 구독의 IoT Hub 아직 허브가 없는 경우 IoT Hub 만들기의 단계를 따를 수 있습니다.

  • IoT Hub에 등록된 디바이스. IoT 허브에 디바이스가 없으면 디바이스 등록의 단계를 따릅니다.

  • 방화벽에서 포트 8883이 열려 있는지 확인합니다. 이 문서의 디바이스 샘플은 포트 8883을 통해 통신하는 MQTT 프로토콜을 사용합니다. 이 포트는 일부 회사 및 교육용 네트워크 환경에서 차단될 수 있습니다. 이 문제를 해결하는 자세한 내용과 방법은 IoT Hub에 연결(MQTT)을 참조하세요.

시뮬레이션된 디바이스 앱 만들기

이 섹션에서는 솔루션 백 엔드에서 호출한 직접 메서드에 응답하는 .NET 콘솔 앱을 만듭니다.

Important

이 문서에서는 공유 액세스 서명(대칭 키 인증이라고도 함)을 사용하여 디바이스를 연결하는 단계를 설명합니다. 이 인증 방법은 테스트와 평가에 편리하지만, X.509 인증서를 사용하여 디바이스를 인증하는 것이 더 안전한 방식입니다. 자세한 내용은 보안 모범 사례 > 연결 보안을 참조하세요.

  1. Visual Studio에서 새 프로젝트 만들기를 선택하고 콘솔 앱(.NET Framework) 프로젝트 템플릿을 선택합니다. 다음을 선택하여 작업을 계속할 수 있습니다.

  2. 새 프로젝트 구성에서 프로젝트 이름을 SimulateDeviceMethods로 지정한 후, 다음을 선택합니다.

    Visual Studio의

  3. .NET Framework의 기본 버전을 수락한 다음, 만들기를 선택하여 프로젝트를 만듭니다.

  4. 솔루션 탐색기에서 SimulateDeviceMethods 프로젝트를 마우스 오른쪽 단추로 클릭한 다음, NuGet 패키지 관리를 선택합니다.

  5. NuGet 패키지 관리자에서 찾아보기를 선택하고 Microsoft.Azure.Devices.Client를 검색한 후 선택합니다. 설치를 선택합니다.

    Visual Studio의 NuGet 패키지 관리자 스크린샷.

    이 단계에서는 Azure IoT 디바이스 SDK NuGet 패키지 및 해당 종속 항목에 참조를 다운로드, 설치 및 추가합니다.

  6. Program.cs 파일 위에 다음 using 문을 추가합니다.

    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.Devices.Shared;
    using Newtonsoft.Json;
    using System.Threading.Tasks;
    using System.Text;
    
  7. Program 클래스에 다음 필드를 추가합니다. 자리 표시자 값을 이전 섹션에서 메모한 디바이스 연결 문자열로 대체합니다.

    static string DeviceConnectionString = "<yourDeviceConnectionString>";
    static DeviceClient Client = null;
    
  8. 다음 코드를 추가하여 디바이스에서 직접 메서드를 구현합니다.

    static Task<MethodResponse> LockDoor(MethodRequest methodRequest, object userContext)
    {
        Console.WriteLine();
        Console.WriteLine("Locking Door!");
        Console.WriteLine("\nReturning response for method {0}", methodRequest.Name);
    
        string result = "'Door was locked.'";
        return Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200));
    }
    
  9. 다음 메서드를 추가하여 디바이스에서 디바이스 쌍 수신기를 구현합니다.

    private static async Task OnDesiredPropertyChanged(TwinCollection desiredProperties, 
      object userContext)
    {
        Console.WriteLine("Desired property change:");
        Console.WriteLine(JsonConvert.SerializeObject(desiredProperties));
    }
    
  10. 마지막으로 Main 메서드에 다음 코드를 추가하여 IoT Hub에 대한 연결을 열고 메서드 수신기를 초기화합니다.

    try
    {
        Console.WriteLine("Connecting to hub");
        Client = DeviceClient.CreateFromConnectionString(DeviceConnectionString, 
          TransportType.Mqtt);
    
        Client.SetMethodHandlerAsync("LockDoor", LockDoor, null);
        Client.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertyChanged, null);
    
        Console.WriteLine("Waiting for direct method call and device twin update\n Press enter to exit.");
        Console.ReadLine();
    
        Console.WriteLine("Exiting...");
    
        Client.SetMethodHandlerAsync("LockDoor", null, null);
        Client.CloseAsync().Wait();
    }
    catch (Exception ex)
    {
        Console.WriteLine();
        Console.WriteLine("Error in sample: {0}", ex.Message);
    }
    
  11. 작업을 저장하고 솔루션을 빌드합니다.

참고 항목

간단히 하기 위해 이 문서에서는 다시 시도 정책을 구현하지 않습니다. 프로덕션 코드에서 일시적인 오류 처리에 제시된 대로 재시도 정책(예: 연결 다시 시도)을 구현해야 합니다.

IoT Hub 연결 문자열 가져오기

이 문서에서는 디바이스에서 직접 메서드를 호출하는 작업을 예약하고, 디바이스 쌍을 업데이트하는 작업을 예약하고, 각 작업의 진행률을 모니터링하는 백 엔드 서비스를 만듭니다. 이러한 작업을 수행하려면 서비스에 레지스트리 읽기레지스트리 쓰기 권한이 있어야 합니다. 기본적으로 모든 IoT Hub는 이 사용 권한을 부여하는 registryReadWrite라는 공유 액세스 정책을 사용하여 만듭니다.

registryReadWrite 정책에 대한 IoT Hub 연결 문자열을 가져오려면 다음 단계를 수행합니다.

  1. Azure Portal에서 리소스 그룹을 선택합니다. 허브가 있는 리소스 그룹을 선택한 다음, 리소스 목록에서 허브를 선택합니다.

  2. 허브의 왼쪽 창에서 공유 액세스 정책을 선택합니다.

  3. 정책 목록에서 registryReadWrite 정책을 선택합니다.

  4. 기본 연결 문자열을 복사하고 값을 저장합니다.

    연결 문자열을 검색하는 방법을 보여 주는 화면 캡처

IoT Hub 공유 액세스 정책 및 사용 권한에 대한 자세한 내용은 액세스 제어 및 권한을 참조하세요.

Important

이 문서에서는 공유 액세스 서명을 사용하여 서비스에 연결하는 단계를 설명합니다. 이 인증 방법은 테스트와 평가에 편리하지만, Microsoft Entra ID나 관리 ID를 사용하여 서비스를 인증하는 것이 더 안전한 방식입니다. 자세한 내용은 보안 모범 사례 > 클라우드 보안을 참조하세요.

직접 메서드를 호출하고 디바이스 쌍의 업데이트를 전송하기 위한 작업 예약

이 섹션에서는 작업을 사용하여 LockDoor 직접 메서드를 호출하고 원하는 속성 업데이트를 여러 디바이스에 전송하는 .NET 콘솔 앱(C# 사용)을 만듭니다.

  1. Visual Studio에서 파일>새로 만들기>프로젝트를 선택합니다. 새 프로젝트 만들기에서 콘솔 앱(.NET Framework)을 선택한 후 다음을 선택합니다.

  2. 새 프로젝트 구성에서 프로젝트 이름을 ScheduleJob으로 지정한 다음, 만들기를 선택합니다.

    ScheduleJob 프로젝트 이름 지정 및 구성

    이름을 추가하는 Visual Studio의

  3. .NET Framework의 기본 버전을 수락한 다음, 만들기를 선택하여 프로젝트를 만듭니다.

  4. 솔루션 탐색기에서 ScheduleJob 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 NuGet 패키지 관리를 선택합니다.

  5. NuGet 패키지 관리자 창에서 찾아보기를 선택하고, Microsoft.Azure.Devices를 검색하여 선택한 다음, 설치를 선택합니다.

    이 단계에서는 Azure IoT 서비스 SDK NuGet 패키지 및 해당 종속 항목에 참조를 다운로드, 설치 및 추가합니다.

  6. Program.cs 파일 위에 다음 using 문을 추가합니다.

    using Microsoft.Azure.Devices;
    using Microsoft.Azure.Devices.Shared;
    
  7. 다음 using 문이 기본 문에 아직 없으면 추가합니다.

    using System.Threading;
    using System.Threading.Tasks;
    
  8. Program 클래스에 다음 필드를 추가합니다. 자리 표시자를 IoT Hub 연결 문자열 가져오기에서 이전에 복사한 IoT Hub 연결 문자열과 디바이스의 이름으로 바꿉니다.

    static JobClient jobClient;
    static string connString = "<yourIotHubConnectionString>";
    static string deviceId = "<yourDeviceId>";
    
  9. Program 클래스에 다음 메서드를 추가합니다.

    public static async Task MonitorJob(string jobId)
    {
        JobResponse result;
        do
        {
            result = await jobClient.GetJobAsync(jobId);
            Console.WriteLine("Job Status : " + result.Status.ToString());
            Thread.Sleep(2000);
        } while ((result.Status != JobStatus.Completed) && 
          (result.Status != JobStatus.Failed));
    }
    
  10. Program 클래스에 다음 메서드를 추가합니다.

    public static async Task StartMethodJob(string jobId)
    {
        CloudToDeviceMethod directMethod = 
          new CloudToDeviceMethod("LockDoor", TimeSpan.FromSeconds(5), 
          TimeSpan.FromSeconds(5));
    
        JobResponse result = await jobClient.ScheduleDeviceMethodAsync(jobId,
            $"DeviceId IN ['{deviceId}']",
            directMethod,
            DateTime.UtcNow,
            (long)TimeSpan.FromMinutes(2).TotalSeconds);
    
        Console.WriteLine("Started Method Job");
    }
    
  11. Program 클래스에 다른 메서드를 추가합니다.

    public static async Task StartTwinUpdateJob(string jobId)
    {
        Twin twin = new Twin(deviceId);
        twin.Tags = new TwinCollection();
        twin.Tags["Building"] = "43";
        twin.Tags["Floor"] = "3";
        twin.ETag = "*";
    
        twin.Properties.Desired["LocationUpdate"] = DateTime.UtcNow;
    
        JobResponse createJobResponse = jobClient.ScheduleTwinUpdateAsync(
            jobId,
            $"DeviceId IN ['{deviceId}']", 
            twin, 
            DateTime.UtcNow, 
            (long)TimeSpan.FromMinutes(2).TotalSeconds).Result;
    
        Console.WriteLine("Started Twin Update Job");
    }
    

    참고 항목

    쿼리 구문에 대한 자세한 내용은 IoT Hub 쿼리 언어를 참조하세요.

  12. 마지막으로 Main 메서드에 다음 줄을 추가합니다.

    Console.WriteLine("Press ENTER to start running jobs.");
    Console.ReadLine();
    
    jobClient = JobClient.CreateFromConnectionString(connString);
    
    string methodJobId = Guid.NewGuid().ToString();
    
    StartMethodJob(methodJobId);
    MonitorJob(methodJobId).Wait();
    Console.WriteLine("Press ENTER to run the next job.");
    Console.ReadLine();
    
    string twinUpdateJobId = Guid.NewGuid().ToString();
    
    StartTwinUpdateJob(twinUpdateJobId);
    MonitorJob(twinUpdateJobId).Wait();
    Console.WriteLine("Press ENTER to exit.");
    Console.ReadLine();
    
  13. 작업을 저장하고 솔루션을 빌드합니다.

앱 실행

이제 앱을 실행할 준비가 되었습니다.

  1. Visual Studio 솔루션 Explorer에서 솔루션을 마우스 오른쪽 단추로 클릭한 다음 시작 프로젝트로 설정을 선택합니다.

  2. 공용 속성>시작 프로젝트, 여러 시작 프로젝트를 차례로 선택합니다.

  3. SimulateDeviceMethods가 목록 맨 위에 표시되고 그 다음으로 ScheduleJob이 표시되는지 확인합니다. 두 작업을 모두 시작으로 설렁하고 확인을 선택합니다.

  4. 시작을 클릭하거나 디버그 메뉴로 이동하여 디버깅 시작을 클릭하여 프로젝트를 실행합니다.

    디바이스 및 백 엔드 앱 모두에서 출력이 표시됩니다.

    작업을 예약하는 앱 실행

다음 단계

이 문서에서는 직접 메서드를 실행하고 디바이스 쌍의 속성을 업데이트하는 작업을 예약했습니다.

IoT Hub 및 디바이스 관리 패턴을 계속 살펴보려면 Raspberry Pi 3 B+ 참조 이미지를 사용하는 Azure IoT Hub용 디바이스 업데이트 자습서에서 이미지를 업데이트합니다.