본문 바로가기

3.구현/HTML5&Javascript

[Javascript] Worker와 Notification

들어가기

Worker은 javascript에서 백그라운드로 돌아가는 프로세스같은 역활을 한다.
Worker 객체를 만들어서 사용하며 백그라운드로 실행될 자바스크립트를 별도로 작성해야 한다.
그리고 Worker 객체와는 메시지를 통해서 데이터를 주고 받을 수 있다.

작성자: ospace114@empal.com, http://ospace.tistory.com/

화면

간단하게 입력받을 화면을 작성한다.

<div>
  <input id="msg" type="text" ><button onclick="onSend()">Send</button>
</div>
<div>Log:</div>
<div id="logger"></div>

Worker

Log 출력을 할 함수를 작성한다.

function log(msg) {
  var span = document.createElement('div');
  span.innerText = msg;
  logger.appendChild(span);
}

Worker 객체를 생성해보자. my_worker.js을 구동한다. 이 파일은 나중에 작성할 예정이다.

var myWorker = new Worker("my_worker.js");

Send 이벤트를 처리할 함수를 작성한다. myWorker객체로 메시지를 보내기 위해서 postMessage()을 사용한다.

function onSend() {
  const value = msg.value;
  msg.value = '';
  myWorker.postMessage([msg.value]);
}

그리고 간단한 작업 처리를 위해 입력창에 엔터키도 연결했다.

msg.addEventListener('keyup', function(ev) {
  if ('Enter' !== ev.key) return;
  ev.preventDefault();
  onSend();
});

myWorker 객체로부터 메시지를 받기 위해 onmessage 핸들러를 작성한다.

myWorker.onmessage = function(e) {
  log(`<< ${e.data}`);
}

마지막으로 my_worker.js 파일을 작성해보자. Worker에서도 메시지를 보내기 위해 postMessage()을 사용한다.

Worker안에서 Subworker을 생성할 수 있다. 이때에는 importScripts()로Worker용 자바스크립트 파일을 불러오면 자동으로 subworker가 생성된다. 즉 subworker와 메시지 주고받을 수단이 없어진다.

부모에서는 subworker 같은 객체로 보고 메시지를 주고 받을 수 있다.

onmessage = function (ev) {
  console.log("> onmessage:", ev, Notification.permission);
  this.postMessage("recved: " + new Date().toISOString());
};

Worker의 동작을 중지하려면

myWorker.terminate()

Notification

Worker와 같이 Notification을 자주사용한다. Worker에서 알람 확인해서 알려주는 역할을 한다.

먼저 Worker에서 처리하기 전에 알람 전송 허용 요청을 처리가 필요하다.

Notification.permission의 default가 아직 결정되지 않은 상태라 허용 요청할수 있다.

denied인 경우는 허용 요청이 처리되지 않으로 granted은 할 필요가 없게 된다.

추가로 현재기준(2022/06/12)에 Chrome와 Edge은 허용요청에 대해 허용이나 거부가 아닌 창을 닫아서 취소할 경우 임시로 denied가 되면서 여러 번 허용 요청을 할 수 있지만, Firefox인 경우는 한번 창을 닫으면 현재 접속된 창에서는 계속 denied가 된다. 다시 리로딩해야 default가 되면서 허용 요청이 된다.

function requestGranted() {
  switch(Notification.permission) {
    case "granted": return Promise.resolve();
    case "denied": return Promise.reject('denied');
    case "default": return new Promise(function(resolve, reject) {
      Notification.requestPermission().then(function(res) {
        if ("granted" === res) return resolve();
        return reject('denied');
      });
    });
  }
}

이를 사용한 onSend()를 변경해보자.

function onSend() {
  const value = msg.value;
  msg.value = '';
  requestGranted().then(()=>{
    myWorker.postMessage([msg.value]);
  }).catch((err)=>{
    console.log(err);
    myWorker.postMessage([msg.value]);
  })
}

그리고 마지막으로 Worker에서는 Notification 처리를 추가한다.

permission이 granted인 경우만 Notification 처리하면 된다.

onmessage = function (ev) {
  console.log("> onmessage:", ev, Notification.permission);
  this.postMessage("recved: " + new Date().toISOString());
  if ("granted" === Notification.permission) {
    new Notification(ev.data.join(","));
  }
};

부족한 글이지만 도움이 되었으면 하네요. 즐프하세요. ospace.

참고

https://developer.mozilla.org/en-US/docs/Web/API/notification

반응형