1. 웹워커 1.1 멀티스레드와웹워커 Ÿ 하나의응용프로그램이스레드라불리는처리단위를복수개생성하여동시에여러기능을수행하는것을멀티스레드 (multi-thread) 라고한다. Ÿ 웹브라우저는싱글스레드를지원한다. 오랜시간걸리는작업이있다면작업이종료될때까지기다려야하고, 복잡한처리과정이진행된다면, 웹브라우저는아마도응답없음상태가되어버릴것이다. 이럴경우, 보통웹브라우저를강제종료한후다시시켜야하는문제가발생할수있다. Ÿ 멀티스레드와유사한개념으로 HTML5에서는웹워커기능이추가되었다. Ÿ 페이지성능에영향을주지않고, 메인이아닌백그라운드에로여러가지복잡한작업도처리가가능하게되었다. Ÿ 웹워커에서사용할수있는기능과접근할수없는기능 사용가능한기능 navigator객체 location 객체 ( 읽기전용 ) XMLHttpRequest settimeout() / cleartimeout() setinterval() / clearinterval() 애플리케이션캐시 ImportScripts() 로외부스크립트가져오기다른웹워커의생성 접근할수없는기능 DOM ( 스레드비보호 ) window 객체 document 객체 parent 객체 1.2 전용워커 Ÿ 메인에서동작하는 UI 스레드와는별개로백그라운드에서여러개의워커들이각각의기능을하며처리동작을하고있는형태로구성한다. Ÿ 메인 UI 문서에서워커역할을하는자바스크립트파일을인수로지정하여워커생성자를호출하여워커를생성한다. var 변수 = new Worker(" 자바스크립트파일.js"); if ( window.worker ) { var worker = new Worker("calc.js"); if ( typeof(worker)!=="undefined" ) { var worker = new Worker("calc.js"); else { // 웹워커미지원 - 1 -
1.2.1 메시지전달 Ÿ 워커에서생성한함수와변수는외부에서호출불가하므로데이터를보내기위해서는 postmessage() 메서드를사용하고, 메서드에전달되는데이터를받기위해서는 onmessage 이벤트핸들러를통해서받아야한다. 1.2.2 워커의생성과메시지전달 1.2.3 워커의오류처리 Ÿ 오류가발생하면 Worker 객체에서 error 이벤트가발생한다. worker.onerror = function(event) { var err_msg = event.message 오류내용을텍스트로반환 + " \n" + event.filename 오류가발생한파일의 URL을완전한 URL(http:// 로시작 ) 로반환 +" 의 "+ event.lineno 오류가발생한줄의번호를반환 + " 번째줄에서오류발생 " alert(err_msg); - 2 -
예제웹워커 메인 UI 스레드 <!DOCTYPE html><html><head> <script> var worker; function calc() { // 실행부분 var num = document.getelementbyid("num").value; worker = new Worker("calc.js"); worker.onmessage = function(event) { //work 에서받은메시지처리 alert(" 약수의개수 : " + event.data); ; worker.onerror = function(event) {alert(" 에러 : " + event.message); ; worker.postmessage(num); // 메시지전달 function stop() { </script> </head> <body> worker.terminate(); // 중지부분 값입력 : <input type="text" id="num"> <input type="button" onclick="calc()" value=" 실행 "> <input type="button" onclick="stop()" value=" 중지 "> </body> </html> 워커 ("calc.js") onmessage = function(event) { ; var i for ( i=num i>0; i-- ) { if ( num % i == 0 ) total++; postmessage(total); // 메시지전달 var num = event. data; var total = 0; 웹서버에서동작화면 - 3 -
1.3 공유워커 Ÿ 여러개의워커객체가하나의백그라운드프로세스를공유해서사용할수있도록하고있다. 하나의워커객체가백그라운드프로세스와일대일대응한다. Ÿ 공유워커객체를생성하기위해서는 SharedWorker() 생성자를호출해야한다. 이렇게생성된공유워커는백그라운드프로세스를공유하게된다. var 변수 = new SharedWorker( 자바스크립트파일명, 워커이름 ); var worker1 = new SharedWorker("calc.js", "share"); var worker2 = new SharedWorker("calc.js", "share"); 1.3.1 공유워커의메시지전달 Ÿ port 속성은메인 UI 문서와공유워커와의통신을위한채널이다. 생성된워커객체의 port 속성을사용해서 postmessage() 메서드를호출해야한다. Ÿ 공유워커에서데이터를전달받기위해사용 onconnect 이벤트를통해서전달받아야한다. onconnect = function(event) { // 메인 UI 스레드와연결되는포트정보확인 // postmessage() 로전달된데이터수신 ; Ÿ 메인 UI 스레드와연결되는포트정보를확인할수있다. ports 속성은배열형태로되어있기때문에 ports 배열의첫번째값을사용하여포트를확인할수있다. Ÿ postmessage() 로전달된데이터를공유워커에서수신한다. port.onmessage = function(event) { // 메시지처리 // 메인 UI 스레드로데이터전달 port.postmessage("result"); ; - 4 -
예제공유워커 메인 UI 스레드 <!DOCTYPE html><html><head> <style> div { background: yellow; padding: 15px; margin: 5px; </style> <script> var worker; border: 1px solid black; border-radius: 15px; window.addeventlistener("load", function() { worker = new SharedWorker("shared_work.js"); // 공유워커생성 worker.port.onmessage = function(event) { print(event.data); // 메시지를수신, false); function send() { // 공유워커로메시지전송 worker.port.postmessage(document.getelementbyid("data").value); function print(msg) { // 메시지를출력한다. var p = document.createelement("p"); p.textcontent = msg; document.getelementbyid("result").appendchild(p); </script> </head> <body> <p> 데이터 <input id="data" type="text" /> <button onclick="send()"> 데이터전송 </button></p> <div><output id="result"></output></div> </body> </html> 워커 ("calc.js") self.onconnect = function(event) { ; var port = event.ports[0]; port.onmessage = function(ev) { ; port.postmessage(" 공유워커메시지 : " + ev.data ); 웹에서결과화면 1.4 워커에서사용가능한 API Ÿ 자바스크립트파일을로드하는방법 - 5 -
self.importscripts("lib1.js"); self.importscripts("lib2.js"); self.importscripts("lib1.js", "lib2.js"); Ÿ 브라우저정보를얻기 self.navigator.appname : 브라우저의이름반환 self.navigator.appversion : 브라우저의버전반환 self.navigator.platform : 운영체제의이름반환 self.navigator.useragent : 웹서버에보낼 User-Agent 헤더의값을반환 self.navigator.online : 네트워크에접속할수없으면 false 반환 Ÿ 워커자바스크립트파일의 URL 정보 다음의 URL이있다고가정한다면 http://dev.w3.org/html5/workers/work.js?arg1=a&arg2=b#apis-available-to-workers 속성 분해내용 의미 self.location.protocol http: 프로토콜 self.location.host dev.w3.org:80 호스트와포트번호 self.location.hostname dev.w3.org 호스트 self.location.port 80 포트번호 self.location.pathname /html5/worker/work.js 경로 self.location.search?arg1=a&arg2=b 질의문 self.location.hash #apis-available-to-workers 해시식별자 2. 웹소켓 2.1 웹페이지요청과문제점 Ÿ 웹은요청 / 응답패러다임기반으로구축되어왔다. 클라이언트가웹문서를로드하고사용자가다음문서를요청하기전까지어떤일도발생하지않는다. 정보를얻기위해서는클라어언트에서서버에항상요청을해야한다. 실시간정보를주고받기위해서는양방향통신이가능해야하고, 이를위해플렉스, 자바애플릿, 실버라이트등을사용한다. 이것들은순수웹환경이아닌별도의런타임을별도의플러그인형태로설 - 6 -
치해야사용가능하다. 2.2 웹소켓 Ÿ 순수웹환경에서실시간양방향통신을위한스펙이다. Ÿ 소켓 은네트워크상에서서버와클라이언트두개의프로그램의특정포트를통해양방향통신이가능하도록만들어주는소프트웨어장치이다. Ÿ 요청을한번만하고웹소켓연결이한번이루어지면, 지속적으로연결된 TCP 라인을통해서버와클라이언트모두언제든지실시간으로메시지를송수신할수있도록하는 HTML5의새로운사양이다. Ÿ 연결지향양방향전이중통신이가능하고웹에서도채팅, 게임, 실시간주식차트와같이실시간이요구되는응용프로그램의한층효과적인구현이가능하다. 2.3 웹소켓생성자를이용한연결설정 Ÿ 서버연결 ( 공개서버 http://www.websocket.org로연결하는것으로가정 ) Ÿ 웹소켓객체생성 2.4 웹소켓속성 속성 url readystate bufferedamount extensions protocol binarytype 설명생성자에전달되는 URL반환웹소켓의연결상태를반환 WebSocket.CONNECTING,WebSocket.OPEN, WebSocket.CLOSING, WebSocket.CLOSED send() 메서드를통해서보내질애플리케이션의데이터의바이트수를반환서버에의해서선택된확장을반환웹소켓생성자에서지정한프로토콜에서서버가선택한프로토콜의이름반환메시지송수신할때이진데이터의경우에는 Blob, 배열버퍼형태로처리할때는 arraybuffer 로지정 - 7 -
2.5 웹소켓이벤트 Ÿ 모든웹소켓 API는이벤트위주로동작된다. 따라서수신되는데이터를처리하고연결상태를변경하기위해서는웹소켓객체를대상으로이벤트를감시하면된다. onopen: 웹소켓연결요청시서버에서응답하여연결이설정되면발생한다. onerror : 예기치못한오류가있을때발생한다. onclose : 웹소켓연결이끊어지면발생한다. onmessage : 메시지가수신되는순간발생한다. websocket. 이벤트 = function(event) { // 해당이벤트에대한처리 ; 2.6 웹소켓메서드 Ÿ send() 메서드를통해서클라이언트에서서버로메시지를전송할수있다. Ÿ close() 메서드는웹소켓의연결을종료시킬수있다. 2.7 웹소켓클라이언트의기본형식 - 8 -
// 서버연결 var websocket = new WebSocket("ws:// "); // 데이터송신 function dosend() { websocket.send("data"); // 데이터수신시호출 websocket.onmessage = function(event) { //( 서버 클라이언트 ) 메시지처리 // 서버연결시호출 websocket.onopen = function(event) { // 이벤트처리 : alert(" 서버연결완료 "); // 서버종료시호출 websocket.onclose = function(event) { // 이벤트처리 : alert(" 서버연결종료 "); 예제웹소켓 <!DOCTYPE html><html><head> <script> var wsuri = "ws://echo.websocket.org/"; var output; function init() { output = document.getelementbyid("output"); testwebsocket(); function testwebsocket() { websocket = new WebSocket(wsUri); // 웹소켓생성 websocket.onopen = function(evt) { onopen(evt) ; // 연결되었을때 websocket.onclose = function(evt) { onclose(evt) ; // 종료되었을때 websocket.onmessage = function(evt) { onmessage(evt) ; // 메시지가수신 websocket.onerror = function(evt) { onerror(evt) ; // 웹소켓오류발생할때 function onopen(evt) { writetoscreen("connected"); dosend("websocket rocks"); function onclose(evt) { writetoscreen("disconnected"); function onmessage(evt) { writetoscreen('<span style="color: blue;">response: ' + evt.data +'</span>'); websocket.close(); function onerror(evt) { writetoscreen('<span style="color:red">error:</span> '+ evt.data); function dosend(message) { writetoscreen("sent: " + message); websocket.send(message); function writetoscreen(message) { var pre = document.createelement("p"); pre.style.wordwrap = "break-word"; pre.innerhtml = message; - 9 -
output.appendchild(pre); window.addeventlistener("load", init, false); </script> </head> <body> <h2>websocket Test</h2> <div id="output"></div> </body> </html> 3. 위치정보 3.1 위치정보 Ÿ 지도서비스 Ÿ 지도를이용한현재의위치정보를검색할때사용하는것이 Geolocation API 이다. Ÿ 위치정보를얻기위해서는사용자의동의를구해야한다. Ÿ 위치정보데이터를얻는방법은 IP 주소기반, GPS 기반, WiFi 기반, 휴대전화기반이있다. 3.2 현재위치정보얻기 Ÿ 현재의위치정보를한번만얻기위해서는 getcurrentposition() 메서드를사용한다. - 10 -
3.2.1 위치정보관련속성 _ 첫번째인자 function MyPosition(position) { document.getelementbyid("latitude").textcontent=position.coords.latitude; // 위도 document.getelementbyid("longitude").textcontent=position.coords.longitude; // 경도 document.getelementbyid("accuracy").textcontent=position.coords.accuracy; // 위도, 경도정밀도 document.getelementbyid("altitude").textcontent=position.coords.altitude; // GPS 고도 document.getelementbyid("altitudeaccuracy").textcontent=position.coords.altitudeaccuracy; // GPS 고도의정밀도 document.getelementbyid("heading").textcontent=position.coords.heading; // 이동방향 ( 각도 ) document.getelementbyid("speed").textcontent=position.coords.speed; // 이동속도 ( 초당미터 ) document.getelementbyid("timestamp").textcontent=position.timestamp; // 위치정보를얻은시각 3.2.2 위치정보오류 _ 두번째인자 Ÿ 위치정보를반드시얻을수있는것은아니므로위치오류정보에대한인터페이스에서정보를얻을수있다. function show_error(error) { switch(error.code) { case error.permission_denied: alert(" 사용권한오류 : " + error.message); break; case error.position_unavailable: alert(" 위치파악오류 : " + error.message); break; case error.timeout: alert(" 시간초과오류 : " + error.message); break; default: alert(" 알수없는오류발생 " + error.message); navigator.geolocation.getcurrentposition(myposition, show_error); 3.2.3 위치정보옵션 _ 세번째인자 Ÿ 위치정보를얻는데소요되는시간및캐시의유효기간을지정하고자한다면세번째 - 11 -
옵션에정보들을설정하면된다. enablehighaccuracytrue : 기본값은 false이고, 정확도가높은위치정보를얻도록요청할때사용한다. timeout : 위치정보를얻을때까지기다릴시간 ( 제한시간 ) 설정한다. maximumage : 캐시된위치정보의유효시간 (ms) 설정한다. 예제 <!DOCTYPE html><html><head> <style>table { width: 450px; th,td { border:1px solid black;</style> <script> window.onload = function() { var options = { enablehighaccuracy: true, // 정확한위치정보요구 timeout: 5000, // 최대대기시간 ( 밀리초 ) maximumage: 0 // 캐시유효시간 ( 밀리초 ) if (navigator.geolocation) navigator.geolocation.getcurrentposition(myposition, show_error, options); function MyPosition(position) { document.getelementbyid("latitude").textcontent = position.coords.latitude; document.getelementbyid("longitude").textcontent = position.coords.longitude; document.getelementbyid("accuracy").textcontent = position.coords.accuracy; document.getelementbyid("altitude").textcontent = position.coords.altitude; document.getelementbyid("altitudeaccuracy").textcontent = position.coords.altitudeaccuracy; document.getelementbyid("heading").textcontent = position.coords.heading; document.getelementbyid("speed").textcontent = position.coords.speed; document.getelementbyid("timestamp").textcontent = position.timestamp; function show_error(error) { // 오류발생시처리할메서드지정 switch(error.code) { case error.permission_denied: alert(" 사용권한오류 :" + error.message ); break; case error.position_unavailable: alert(" 위치파악오류 :" + error.message ); break; case error.timeout: alert(" 시간초과오류 : " + error.message ); break; default: alert(" 알수없는오류발생 " + error.message ); break; </script> </head> <body> <h2>geolocation API - 위치정보나타내기 </h2><hr /> <table> - 12 -
<tr><th> 상세한내용 </th><th> 위치정보 </th></tr> <tr><td> 위도 </td><td id="latitude">.</td></tr> <tr><td> 경도 </td><td id="longitude">.</td></tr> <tr><td> 위도및경도의정밀도 </td><td id="accuracy">.</td></tr> <tr><td>gps 고도 </td><td id="altitude">.</td></tr> <tr><td>gps 고도의정밀도 </td><td id="altitudeaccuracy">.</td></tr> <tr><td> 이동방향 </td><td id="heading">.</td></tr> <tr><td> 이동속도 </td><td id="speed">.</td></tr> <tr><td> 위치정보를획득한시간 </td><td id="timestamp">.</td></tr> </table> </body> </html> 3.3 연속적인위치정보얻기 Ÿ 현재의연속적인위치정보를얻기위해서는 watchposition() 메서드를사용한다. Ÿ clearwatch() 메서드를호출하기전까지는계속해서위치정보를감시한다. clearwatch() 메서드에서는 watchposition() 메서드호출시에반환되는식별 ID를인수로지정한다. var 식별ID=navigator.geolocation.watchPosition(successCallback, errorcallback, options); navigator.geolocation.clearwatch( 식별ID); 3.4 구글지도활용하기 Ÿ Google Maps Javascript API v3는공식적으로무료인자바스크립트 API이다. https://developers.google.com/maps/documentation/javascript/tutorial?h1=ko Ÿ 지도서비스관련 API 제공사이트네이버지도 http://developer.naver.com/wiki/pages/mapapi 다음지도 API 3 http://dna.daum.net/apis/maps 예제지도서비스활용 <!DOCTYPE html> <html> <head> <style> html, body, #map-canvas { height: 100%; margin: 0px; padding: 0px </style> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script> <script> var map, lat = 37.5010226, lng = 127.0396037; function initialize() { - 13 -
var mapoptions = { zoom: 12, // 지도의확대비율을지정한다. center: new google.maps.latlng(lat, lng), // 현재의위치정보를기준으로한다. maptypeid: google.maps.maptypeid.roadmap ; // 현재지도를중심으로구글지도를표시하도록한다. map = new google.maps.map(document.getelementbyid('map-canvas'), mapoptions); google.maps.event.adddomlistener(window, 'load', initialize); </script> </head> <body> <div id="map-canvas" style="width:500px;height:500px"></div> </body> </html> - 14 -