작업 예약 및 브로드캐스트(Node.js)
Azure IoT Hub를 사용하여 수백만 대의 디바이스를 업데이트하는 작업을 예약하고 추적합니다. 작업을 사용하여 다음을 수행합니다.
- desired 속성 업데이트
- tags 업데이트
- 직접 메서드 호출
개념적으로 작업(job)은 이러한 작업(action) 중 하나를 래핑하고 디바이스 쌍 쿼리로 정의된 디바이스 집합에 대해 실행 진행 상태를 추적합니다. 예를 들어 백 엔드 앱은 작업을 사용하여 디바이스 쌍 쿼리로 지정되고 향후에 예약된 10,000개 디바이스에서 다시 부팅 메서드를 호출할 수 있습니다. 그러면 이러한 각 디바이스에서 다시 부팅 메서드를 받고 실행할 때 해당 애플리케이션에서 진행 상황을 추적할 수 있습니다.
이러한 기능에 대한 자세한 내용은 다음 문서를 참조하세요.
디바이스 쌍 및 속성: 디바이스 쌍 시작 및 IoT Hub의 디바이스 쌍 이해 및 사용
직접 메서드: IoT Hub 개발자 가이드 - 직접 메서드
참고 항목
이 문서에서 설명하는 기능은 IoT Hub의 표준 계층에서만 사용할 수 있습니다. 기본 및 표준/무료 IoT Hub 계층에 대한 자세한 내용은 솔루션에 적합한 IoT Hub 계층 선택을 참조하세요.
이 문서에서는 2개의 Node.js 앱을 만드는 방법을 보여 줍니다.
백 엔드 앱에 의해 호출될 수 있는 lockDoor라는 직접 메서드를 구현하는 simDevice.js라는 Node.js 시뮬레이션된 디바이스 앱을 만듭니다.
2개의 작업을 만드는 scheduleJobService.js라는 Node.js 콘솔 앱을 만듭니다. 한 작업은 lockDoor 직접 메서드를 호출하고 다른 작업은 원하는 속성 업데이트를 여러 디바이스로 보냅니다.
참고 항목
디바이스 및 백 엔드 앱을 빌드하는 데 사용할 수 있는 SDK 도구에 대한 자세한 내용은 Azure IoT SDK를 참조하세요.
필수 조건
Azure 구독의 IoT Hub 아직 허브가 없는 경우 IoT Hub 만들기의 단계를 따를 수 있습니다.
IoT Hub에 등록된 디바이스. IoT 허브에 디바이스가 없으면 디바이스 등록의 단계를 따릅니다.
Node.js 버전 10.0.x 이상. 개발 환경 준비에서는 Windows 또는 Linux에 이 문서의 Node.js를 설치하는 방법을 설명합니다.
방화벽에서 포트 8883이 열려 있는지 확인합니다. 이 문서의 디바이스 샘플은 포트 8883을 통해 통신하는 MQTT 프로토콜을 사용합니다. 이 포트는 일부 회사 및 교육용 네트워크 환경에서 차단될 수 있습니다. 이 문제를 해결하는 자세한 내용과 방법은 IoT Hub에 연결(MQTT)을 참조하세요.
시뮬레이션된 디바이스 앱 만들기
이 섹션에서는 클라우드에서 호출한 메서드에 응답하는 Node.js 콘솔 앱을 만듭니다. 이 메서드는 시뮬레이션된 lockDoor 메서드를 트리거합니다.
Important
이 문서에서는 공유 액세스 서명(대칭 키 인증이라고도 함)을 사용하여 디바이스를 연결하는 단계를 설명합니다. 이 인증 방법은 테스트와 평가에 편리하지만, X.509 인증서를 사용하여 디바이스를 인증하는 것이 더 안전한 방식입니다. 자세한 내용은 보안 모범 사례 > 연결 보안을 참조하세요.
simDevice라는 빈 폴더를 새로 만듭니다. simDevice 폴더의 명령 프롬프트에서 다음 명령을 사용하여 package.json 파일을 만듭니다. 모든 기본값을 수락합니다.
npm init
simDevice 폴더의 명령 프롬프트에서 다음 명령을 실행하여 azure-iot-device 디바이스 SDK 패키지 및 azure-iot-device-mqtt 패키지를 설치합니다.
npm install azure-iot-device azure-iot-device-mqtt --save
텍스트 편집기를 사용하여 simDevice 폴더에 새 simDevice.js 파일을 만듭니다.
simDevice.js 파일 앞에 다음 'require' 문을 추가합니다.
'use strict'; var Client = require('azure-iot-device').Client; var Protocol = require('azure-iot-device-mqtt').Mqtt;
connectionString 변수를 추가하고 이 변수를 사용하여 클라이언트 인스턴스를 만듭니다.
{yourDeviceConnectionString}
자리 표시자 값을 이전에 복사한 디바이스 연결 문자열로 바꿉니다.var connectionString = '{yourDeviceConnectionString}'; var client = Client.fromConnectionString(connectionString, Protocol);
다음 함수를 추가하여 lockDoor 메서드를 처리합니다.
var onLockDoor = function(request, response) { // Respond the cloud app for the direct method response.send(200, function(err) { if (err) { console.error('An error occurred when sending a method response:\n' + err.toString()); } else { console.log('Response to method \'' + request.methodName + '\' sent successfully.'); } }); console.log('Locking Door!'); };
다음 코드를 추가하여 lockDoor 메서드에 대한 처리기를 등록합니다.
client.open(function(err) { if (err) { console.error('Could not connect to IotHub client.'); } else { console.log('Client connected to IoT Hub. Register handler for lockDoor direct method.'); client.onDeviceMethod('lockDoor', onLockDoor); } });
simDevice.js 파일을 저장하고 닫습니다.
참고 항목
간단히 하기 위해 이 문서에서는 다시 시도 정책을 구현하지 않습니다. 프로덕션 코드에서는 문서 일시적인 오류 처리에서 제시한 대로 다시 시도 정책(예: 지수 백오프)을 구현해야 합니다.
IoT Hub 연결 문자열 가져오기
이 문서에서는 디바이스에서 직접 메서드를 호출하는 작업을 예약하고, 디바이스 쌍을 업데이트하는 작업을 예약하고, 각 작업의 진행률을 모니터링하는 백 엔드 서비스를 만듭니다. 이러한 작업을 수행하려면 서비스에 레지스트리 읽기 및 레지스트리 쓰기 권한이 있어야 합니다. 기본적으로 모든 IoT Hub는 이 사용 권한을 부여하는 registryReadWrite라는 공유 액세스 정책을 사용하여 만듭니다.
registryReadWrite 정책에 대한 IoT Hub 연결 문자열을 가져오려면 다음 단계를 수행합니다.
Azure Portal에서 리소스 그룹을 선택합니다. 허브가 있는 리소스 그룹을 선택한 다음, 리소스 목록에서 허브를 선택합니다.
허브의 왼쪽 창에서 공유 액세스 정책을 선택합니다.
정책 목록에서 registryReadWrite 정책을 선택합니다.
기본 연결 문자열을 복사하고 값을 저장합니다.
IoT Hub 공유 액세스 정책 및 사용 권한에 대한 자세한 내용은 액세스 제어 및 권한을 참조하세요.
Important
이 문서에서는 공유 액세스 서명을 사용하여 서비스에 연결하는 단계를 설명합니다. 이 인증 방법은 테스트와 평가에 편리하지만, Microsoft Entra ID나 관리 ID를 사용하여 서비스를 인증하는 것이 더 안전한 방식입니다. 자세한 내용은 보안 모범 사례 > 클라우드 보안을 참조하세요.
직접 메서드를 호출하고 디바이스 쌍의 속성을 업데이트하기 위한 작업 예약
이 섹션에서는 직접 메서드를 사용하여 디바이스에서 원격 lockDoor를 시작하는 Node.js 콘솔 앱을 만들고 디바이스 쌍의 속성을 업데이트합니다.
scheduleJobService라는 빈 폴더를 새로 만듭니다. scheduleJobService 폴더의 명령 프롬프트에서 다음 명령을 사용하여 package.json 파일을 만듭니다. 모든 기본값을 수락합니다.
npm init
scheduleJobService 폴더의 명령 프롬프트에서 다음 명령을 실행하여 azure-iothub 디바이스 SDK 패키지 및 azure-iot-device-mqtt 패키지를 설치합니다.
npm install azure-iothub uuid --save
텍스트 편집기를 사용하여 scheduleJobService 폴더에 새 scheduleJobService.js 파일을 만듭니다.
scheduleJobService.js 파일의 시작 부분에 다음 'require' 문을 추가합니다.
'use strict'; var uuid = require('uuid'); var JobClient = require('azure-iothub').JobClient;
다음 변수 선언을 추가합니다.
{iothubconnectionstring}
자리 표시자 값을 IoT 허브 연결 문자열 가져오기에서 복사한 값으로 바꿉니다. myDeviceId 이외의 다른 디바이스를 등록한 경우 쿼리 조건에서 변경해야 합니다.var connectionString = '{iothubconnectionstring}'; var queryCondition = "deviceId IN ['myDeviceId']"; var startTime = new Date(); var maxExecutionTimeInSeconds = 300; var jobClient = JobClient.fromConnectionString(connectionString);
작업 실행을 모니터링하는 데 사용되는 다음 함수를 추가합니다.
function monitorJob (jobId, callback) { var jobMonitorInterval = setInterval(function() { jobClient.getJob(jobId, function(err, result) { if (err) { console.error('Could not get job status: ' + err.message); } else { console.log('Job: ' + jobId + ' - status: ' + result.status); if (result.status === 'completed' || result.status === 'failed' || result.status === 'cancelled') { clearInterval(jobMonitorInterval); callback(null, result); } } }); }, 5000); }
디바이스 메서드를 호출하는 작업을 예약하도록 다음 코드를 추가합니다.
var methodParams = { methodName: 'lockDoor', payload: null, responseTimeoutInSeconds: 15 // Timeout after 15 seconds if device is unable to process method }; var methodJobId = uuid.v4(); console.log('scheduling Device Method job with id: ' + methodJobId); jobClient.scheduleDeviceMethod(methodJobId, queryCondition, methodParams, startTime, maxExecutionTimeInSeconds, function(err) { if (err) { console.error('Could not schedule device method job: ' + err.message); } else { monitorJob(methodJobId, function(err, result) { if (err) { console.error('Could not monitor device method job: ' + err.message); } else { console.log(JSON.stringify(result, null, 2)); } }); } });
디바이스 쌍을 업데이트하는 작업을 예약하도록 다음 코드를 추가합니다.
var twinPatch = { etag: '*', properties: { desired: { building: '43', floor: 3 } } }; var twinJobId = uuid.v4(); console.log('scheduling Twin Update job with id: ' + twinJobId); jobClient.scheduleTwinUpdate(twinJobId, queryCondition, twinPatch, startTime, maxExecutionTimeInSeconds, function(err) { if (err) { console.error('Could not schedule twin update job: ' + err.message); } else { monitorJob(twinJobId, function(err, result) { if (err) { console.error('Could not monitor twin update job: ' + err.message); } else { console.log(JSON.stringify(result, null, 2)); } }); } });
scheduleJobService.js 파일을 저장하고 닫습니다.
애플리케이션 실행
이제 애플리케이션을 실행할 준비가 되었습니다.
simDevice 폴더의 명령 프롬프트에서 다음 명령을 실행하여 다시 시작 직접 메서드에 대한 수신 대기를 시작합니다.
node simDevice.js
scheduleJobService 폴더의 명령 프롬프트에서 다음 명령을 실행하여 도어를 잠그고 쌍을 업데이트하는 작업을 트리거합니다.
node scheduleJobService.js
콘솔에서 직접 메서드 및 작업 상태에 대한 디바이스 응답을 볼 수 있습니다.
다음은 직접 메서드에 대한 디바이스 응답을 보여줍니다.
다음은 직접 메서드 및 디바이스 쌍 업데이트에 대한 서비스 예약 작업과 완료될 때까지 실행되는 작업을 보여줍니다.
다음 단계
이 문서에서는 직접 메서드를 실행하고 디바이스 쌍의 속성을 업데이트하는 작업을 예약했습니다.
IoT Hub 및 디바이스 관리 패턴을 계속 살펴보려면 Raspberry Pi 3 B+ 참조 이미지를 사용하는 Azure IoT Hub용 디바이스 업데이트 자습서에서 이미지를 업데이트합니다.