2011년 8개 IT 메가 트렌드, HTML5 역할 언급

Posted in 모바일/HTML5 // Posted at 2010. 10. 21. 16:44
기사원문: 삼성SDS, 내년 IT 이끌어 갈 8개 트렌드 발표

삼성SDS가 2011년 IT 메가트랜드를 발표했다

소셜, 개방, 스마트, 클라우드, 하이브리드 등이 핵심키워드로 선정되었는데 이중 하이브리드 웹이라는 주제에서 HTML5 의 역할이 정의 되어 있다

[현상]
HTML5와 같은 차세대 웹 표준의 등장으로 기존의 RIA 플랫폼 기능들이 표준웹으로 통합되며, Web기반 OS, Web App Store등장 등으로 Web이 점차 App과 유사해 지고 있다.

[발전방향]
HTML5는 궁극적으로 오디오, 동영상, 쌍방향 플러그인 등을 필요 없게 만들 것이며, App과 Web은 서로 간의 장단점을 보완하며 궁극적으로 하나의 시스템으로 통합되어 갈 것이다
HTML5 가 가까운 미래 IT 환경에서 요직(?)을 차지하게 될 것이라는 분석에 동의한다
Tags html5

submit

HTML5 에는 로컬 자원을 활용하는 유용한 기능들이 포함되어 있다
대표적인 예로 웹 스토로지, 웹 데이타베이스, 어플리케이션 캐시등을 들 수 있다

이 블로그에서 이 들 스펙에 대해 간략하게 다루었었다
: [HTML5] Web Storage
: [HTML5] 오프라인 웹 어플리케이션
: [HTML5] Web SQL Database

이와같은 로컬 자원을 활용하면 웹 응용프로그램의 사용성, 응답성, 성능등과 같은 전반적인 효율성을 꾀할 수 있어 많은 활용도가 기대된다

이들 기술의 기능적 구현에 대한 이해와 더불어 환경에 대한 이해도 같이 해 두면 유용할 것이다
이전 글에서는 기술의 개요와 구현에 대해 살펴보았다면 이 글에서는 로컬 자원의 저장 위치와 한계 용량, 지속 기간 등의 환경적 요인들을 살펴 보고 이들 기술의 이해의 폭을 넓히고자 한다

그럼 이제부터 HTML5에서 로컬 자원을 어디에, 얼마나, 언제까지 저장하는지 살펴 보도록 하자.
참고로 로컬 영역에 대한 내용이다 보니 클라이언트 PC의 OS와 브라우저의 종류, 버전에 따라  내용이 조금씩 다를 수 있음을 밝혀 둔다. 그리고 가정을 하건대, 로컬 디스크의 용량은 무제한이라고 가정해 둔다. 기술별 최대 용량을 따져보는 와중에 컴퓨터 하드디스크 자체에 여유공간이 없다면 아무런 소용이 없기 때문이다

이 글은 윈도우 XP를 사용하고 IE8, 그외 브라우저(크롬,사파리등)은 현재시점(2010.10.19) 최신버전을 사용하고 있는 것을 기준으로 하고 있다

어디에 저장되는가?
대부분의 로컬자원은 OS의 사용자별 어플리케이션 데이터 공간에 저장된다
윈도우 XP에서는 'C:\Documents and Settings\사용자계정\Local Settings\Application Data' 가 어플리케이션 데이터를 저장하는 공간이며 이 디렉터리 하위에 있는 각 브라우저별 폴더에 로컬자원이 저장된다
윈도우에서 'C:\Documents and Settings\사용자계정' 의 경로는 %userprofile%로 대체 된다

LocalStorage
크롬: %userprofile%\Local Settings\Application Data\Google\Chrome\User Data\Default\Local Storage
사파리: %userprofile%\Local Settings\Application Data\Apple Computer\Safari\LocalStorage
파폭: %userprofile%\mkex\Application Data\Mozilla\Firefox\Profiles\xxx.default\webappsstore.sqlite 파일
오페라: %userprofile%\Application Data\Opera\Opera\pstorage
IE8: %userprofile%\Local Settings\Application Data\Microsoft\Internet Explorer\DOMStore

SessionStorage
세션스토로지의 경우 브라우저 프로세스의 메모리 영역에 저장되므로 물리적인 시스템 디렉터리에 저장되지 않는다. 따라서 데이터 저장을 위한 별도의 디렉터리 경로가 없다

Web SQL Database
크롬: %userprofile%\Local Settings\Application Data\Google\Chrome\User Data\Default\databases
사파리: %userprofile%\Local Settings\Application Data\Apple Computer\Safari\Databases
파폭: 지원되지 않음
오페라: %userprofile%\Application Data\Opera\Opera\pstorage

Application Cache
크롬: %userprofile%\Local Settings\Application Data\Google\Chrome\User Data\Default\Application Cache
사파리: %userprofile%\Local Settings\Application Data\Apple Computer\Safari\ApplicationCache.db 파일
파폭: %userprofile%\Local Settings\Application Data\Mozilla\Firefox\Profiles\xxxxx.default\OfflineCache
오페라: %userprofile%\Local Settings\Application Data\Opera\Opera\application_cache


얼마나 저장되는가?
LocalStorage
로컬스토로지의 경우 브라우저마다 최대 저장용량이 다를 수 있다. 더 엄밀히 말하면 브라우저, 도메인마다 최대 용량이 다를 수 있다. 로컬스토로지는 같은 도메인 정책보안을 따르기 때문에 최대 용량 역시 도메인별로 한정을 하고 있다. 예를 들어 파이어폭스는 도메인당 최대 5MB 까지 가능하다
표준 스펙에 의하면 5MB를 최대 용량으로 권장하고 있으니 대체로 다른 브라우저도 이와 비슷할 것으로 보인다. 만일 한 도메인에 localStorage의 값을 5MB 이상 저장해야 한다면 브라우저가 이를 지원하는지 따져봐야 한다. (IE8의 경우 도메인당 10MB를 지원하는 것 같다)
(기존 쿠키가 4KB로 제한을 둔 것에 비하면 5MB 공간은 웹 환경에서 상당량이라 할 수 있다) 

SessionStorage
세션스토로지의 경우 전역적인 공간이 아닌 브라우저 컨텍스트 영역에 저장되므로 브라우저 프로세스, 메모리와 연관이 있다. 이런 특징에 기인했는지 최대용량에 대한 언급을 찾을 수 없다. 다시 말해 브라우저 자체적으로 용량에 대한 제한을 두는지 localStorage 와 합쳐서 도메인당 용량을 계산하는지 아니면 브라우저 컨텍스트에서 사용 가능한 시스템의 메모리 크기에 의존하는지 등에 대한 언급은 없지만 개인적으로는 후자, 즉 브라우저 프로세스가 사용하는 시스템 메모리 크기에 의존하지 않을까 예상해 본다

Web SQL Database
웹 데이터베이스 용량의 기준은 LocalStorage와 개념적으로 유사하다.
즉 브라우저별로 최대 용량이 다를 수 있으며 도메인 단위로 관리된다.
그러나 LocalStorage 비해 용량의 유연성이 더 크다. 다시말해 더 큰 크기의 데이터저장이 가능하다는 것이다
HTML5 표준 사양에는 DB 용량에 대한 규정을 별도로 두지 않고 있으며 브라우저의 정책에 따라  DB용량의 기준이 다를 수 있다는 것을 명심하자DB를 생성하는 openDatabase 함수의 estimatedSize 매개변수에 생성하고자 하는 DB의 크기를 바이트 단위로 지정할 수 있는데 이 크기는 DB의 대략적인 크기를 지정하는 것으로 브라우저마다 그 적용이 다를 수 있다는 것이다.
openDatabase(in DOMString name, in DOMString version, in DOMString displayName, 
                                         in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);


사파리 브라우저를 통해 DB 용량에 대한 내용을 체크 해 보자
다음 코드와 같이 기가(GB)단위의 큰 DB를 생성한다

var db = window.openDatabase("myDB","1.0", "테스트용DB", 1024*1024*1024);

사파리에서 위 코드를 실행하면 다음 그림과 같이 허용할 것인지 대화상자가 나오고 사용자가 허용하면 정상적으로 DB가 생성된다. (심지어 크롬과 오페라는 허용 여부를 묻지도 않고 생성해 준다)



그러나 브라우저마다 기본적으로 설정한 기본 크기는 있다. 사파리의 경우 기본 5MB 이며 환경설정에서 이를 변경할 수 있다. 아래화면은 '사파리의 기본설정->보안탭 화면' 인데 기본 5MB 설정에, 500M까지 변경 가능하다. 여기에서 설정한 기본크기 보다 작은 크기의 DB를 생성하면 자동으로 기본크기가 적용되며 반대로 기본크기보다 큰 DB를 생성하면 앞서 본것과 같이 허용을 묻는 대화상자가 나타나는 것이다
이때 openDatabase에서 명시한 DB크기가 설정되는 것이 아니라 브라우저의 임의의 계산식에 의해 좀더 넉넉한 공간을 확보하게 되는데 위 예에서 1G DB를 생성했는데 1.2G 로 잡힌 이유도 여기에 있다


이렇듯 사파리에서는 DB크기를 유연하게 관리하는 것으로 미루어보건대, 만일 기존에 생성된 DB의 크기보다 더 큰 데이터를 입력하려고 하면 자동으로 크기가 일정부분 확대될 것으로 예상된다
(일반적인 DBMS 가 그러한 것 처럼...)

참고로 기존에 생성된 DB의 크기를 다음과 같이 수동으로 변경이 가능하다.
아래 화면은 사파리에의서 기존에 생성된 DB를 도메인별로 나타내고 각 DB의 현재 크기와 최대 크기를 명시하고 있는 화면이다. 여기서 도메인별 DB 최대 크기를 사용자가 변경할 수 있다


크롬브라우저는 '옵션->고급설정탭->컨텐츠설정->쿠키->쿠키및기타사이트데이터표시'에서 확인 가능하다


오페라브라우저는 '설정->환경설정->고급설정탭->저장공간'에서 확인 가능하다


결론적으로 웹 데이타베이스의 용량은 특별히 제한을 가해 두지 않은 듯 하며 유연한 확장이 가능해 보인다
다만 브라우저마다 그 기준이 다를 수 있기 때문에 필요할 경우 브라우저 사양서을 확인하면 좋을 것이다

용량에 특별히 제한을 가해 두지 않았다는 것이 무제한으로 사용가능하다는 의미는 아니다.
당연하겠지만 하드디스크의 용량을 넘어설 수 없으며 그게 아니더라도 너무 무리한 용량은 예상치 않은 동작을 유발할 수도 있다. 사파리의 경우 자동으로 계산되는 최대크기가 매우 가변적인다.

예를들어 10G로 생성하면 2.3G로 잡고 7G로 생성하면 3.4G로 잡고 100G로 잡으면 최대크기는 오히려 기본크기로 잡히는 등 예측할 수 없는 결과를 보여 주고 있다. 따라서 너무 무리한 크기 설정은 피하는 것이 좋으며 서버급 DB가 아닌 로컬 DB에서 이와같이 과도한 크기를 이용하는 시나리오가 있다면 설계를 잘 못한 것일 수도 있다. 그리고 최대크기라는 기준이 큰 의미가 없을 수도 있다. 사파리에서 최대크기를 명시하더라도 실제 데이터를 저장하고 있는 시스템 디렉터리 파일은 현재크기로만 존재한다. 그리고 데이터 입력이 증가할 수록 용량은 점점 확장된다.

결론적으로 특별히 제한을 가해 두지 않았다는 의미는 사용할 만큼의 충분한 공간을 제공한다 라는 의미로 해석하기 바란다


Application Cache
어플리케이션 캐시의 저장 용량을 따져보는 것은 어찌보면 무의미 할 수 있다
로컬스토로지나 웹데이타베이스와 같은 것은 저장소라는 개념이 명확해서 사용 가능한 공간, 용량이라는 개념을 적용시킬 수 있으나 어플리케이션 캐시는 이런 개념과는 조금 다르기 때문이다.
그러나 이것 역시 로컬의 어딘가에 저장되어 캐시 되기에 굳이 용량에 대한 관점으로 본다고 하면, 어플리케이션 캐시가 저장되는 시스템 하드디스크의 크기라고 말할 수 있겠다.

다만 IE의 임시인터넷파일과 같이 저장공간에 제한을 둘 수도 있는데 이것과 관련해서도 역시 각 브라우저 정책에 따른다는 것이다.

HTML5 스펙에서는 어플리케이션 캐시에 대한 디스크 공간을 다음과 같이 설명하고 있다.
User agents should consider applying constraints on disk usage of application caches.
User agents should allow users to see how much space each domain is using, and may offer the user the ability to delete specific application caches.
 


언제까지 저장되는가?
LocalStorage
로컬스토로지는 특수한 상황이 아니라면 영구적으로 데이터를 보관한다
특수한 상황이라 하면, 사용자가 직접 데이터를 삭제하거나 브라우저를 제거하거나 OS를 재설치하는 것을 말한다. 이러한 특수한 상황이 아니라면 데이터는 영구적으로 보관된다

SessionStorage
세션스토로지는 브라우저 창이 닫힐 때 까지 보관된다. 엄밀히 말하면 브라우저컨텍스트라는 일종의 프로세스 도메인이 활성화되어 있는 동안만 데이터가 유지된다. 쉽게 말해 브라우저 창이 열려 있는 동안 데이터가 보관 된다고 생각하면 되겠다

Web SQL Database
웹 데이터베이스는 LocalStorage와 같이 특수한 상황이 아니라면 영구적으로 데이터를 보관한다

Application Cache
어플리케이션 캐시에 보관되는 데이터의 유효기간을 따지는 것은 앞서 용량을 따지는 것보다 더 무의미하다
앞서 다른 기술들과 마찬가지로 특수한 상황이 아니라면 영구적으로 보관될 것이며 캐시를 업데이트 하거나 캐시 저장공간이 꽉 찾을 경우 덮어 쓰는 등의 시나리오에서 일부 갱신되거나 유실될 수 있을 것이다

Tags html5

submit
태생적으로 웹은 로컬 혹은 네이티브 환경보다 느릴 수 밖에 없는 구조이다

HTML5 의 등장으로 웹이 응용프로그램화가 가능해졌다고는 하지만 웹이라는 환경에 기인하는 이상 네이티브 응용프로그램의 속도나 성능을 기대하기는 어렵다는 것이 사실이다

HTML5를 적극 지지하는 한 사람인 필자 역시 이 부분은 냉정하게 생각해봐야 한다고 본다
혹여 누군가, HTML5만 이용하면 기존 응용프로그램의 수준과 동일하게 구현할 수 있다고 한다면 일단 의심해 봐야 한다. 그 수준이라는 것이 기능적인 측면에서만 바라본다면 그럴 수 있으나 속도나 보안성과 같은 응용프로그램의 기능,비기능적 측면을 모두 따져 본다면 결코 만만한 것이 아니다

예컨대 오프라인 어플리케이션 캐시, 웹 워커, 웹 스토로지, 웹 데이타베이스를 활용해 응용프로그램의 성능을 향상시킬 수 있으며 현재 가속화되고 있는 브라우저 성능 개선도 웹 응용프로그램의 성능향상에 상당부분 기여한다. 하지만 저 건너편, 웹에 있는 원격지의 데이터에 많은 부분 의존할 수 밖에 없는 환경과 OS위에서 동작하는 브라우저 환경, 인터프리터 방식의 해석 환경, 전송계층보다 한단계 위인 응용계층의 통신 활용이 빈번한 웹이 네이티비의 그것과 완전성을 같이 한다는 것은 어불성설이다

이러한 문제는 시각의 차이에서 기인하기도 한다.
과연 웹 응용프로그램이 네이티브응용프로그램과 그 성격이 같으냐는 문제를 고려해 봐야 한다
HTML5가 추구하는 바가 웹이 모든 네이티브 응용환경을 대체하겠다는 것은 아니다
기존의 웹 보다 그 경계를 낮출 수 있는 수단으로써의 웹이 어찌보면 더 적합할 수도 있다
물론 웹이 네이티브 환경보다 더 많이 가진 여러 장점들은 일일이 논하지 않겠다

HTML5에 대한 업계, 개발자, 사용자의 기대가 큰 것은 좋은 현상이다
태생적으로 다른 두 환경을 동일시 하기는 힘들지만 그럼에도 불구하고 이런 기대를 져버리지 않기 위해 분명 고래해 볼 점은 있겠다.

넘을 수 있는 벽인가 아닌가를 따지는 것도 중요하지만 그 전에 HTML5 그리고 웹환경이 가진 일종의 단점을 집어 보자. 대표적으로 다음의 3가지를 들 수 있겠다

- 느린 속도
이건 HTML5의 단점이 아니라 웹의 단점이다. 오히려 HTML5는 느린 웹을 향상시켰다
그러나 여전히 네이티브의 그것과 비교하면 느릴 수 밖에 없다.
전용 앱이 아닌 모바일 웹을 채택하지 못하는 많은 이유가 여기에 기인하기도 한다

- 불안한 호환성
이건 언젠가 해결될 문제이기도 하다
현재 HTML5 를 지원하는 브라우저마다 조금씩 다른 지원형태를 보인다
상용 서비스를 개발하는 입장에서 참으로 피곤한 문제라 하겠다

- 느린 대응
예전부터 HTML5 표준화 시점에 대해 말이 많았다
한 업체에서 주도적으로 개발하는 다른 제품과는 달리 여러 업체가 그것도 표준화 기구와 맞물려 작업을 하다 보니 느릴 수 밖에 없다. 실시간 환경, 급변하는 환경에서는 어울리지 않는다
표준화가 완료되더라도 이후 환경변화에 대한 빠른 대응이 가능할지 의문이 드는 대목이다


그래서 최적이 중요하다
웹의 장점, 웹의 단점, 웹의 이상, 웹의 한계, 그리고 비즈니스의 접목...
모든 것이 가능하지도 모든 것이 불가능하지도 않다는 시각. 다만 최적의 방안만이 존재한다는 시각.
이런 시각을 위해서는 정확한 지식과 유연한 지혜가 필요하다

HTML5 가 대세이며 그가 할 수 있는 일은 매우 많으며 우리 비즈니스를 이렇게 해결할 수 있겠다라는 청사진을 제시할 수 있으려면 HTML5의 한계, 나아가 웹의 한계에 대해서도 정확히 집어 낼 수 있어야 하겠다

=> [m오피스 프레임워크③]MEAP 도입의 고려 사항그리고 느린 표준화?
Tags html5

submit

MKEXDev.NET 의 로고가 필요하게 된 적이 있었다

대학생에게 무료로 개발도구를 배포하는 마이크로소프트의 DreamSpark 이벤트에 후원 커뮤니티로 선정되어 사이트 로고를 보내줘야 했다. 당시 내 사이트에는 특별한 로고가 없었으나 MS 프로모션 담당자는 이미지로 된 로고를 원했다. 그래서 급조하기로 했는데 개발을 주제로 한 사이트라 뭐.. 특별한 디자인을 하고 싶지는 않았다. 그냥 텍스트에 간단한 효과를 줘서 깔끔하게만 보이면 되겠다 싶었다.

그래서 아는 디자이너에게 매우 심플하게 만들어 달라고 부탁해서 나온 로고가 바로 아래와 같은 모습니다.
심플하면서도 깔끔한 텍스트 기반의 로고로 개인적으로 흡족하며 지금까지 사이트 로고로 사용하고 있다



이를 계기로 문득, 텍스트를 입력하면 간단한 효과만 처리해서 이미지로 변환해 주는 툴이 있으면 좋겠다는 생각이 들었는데 마침 HTML5를 접하면서 간단하게라도 데모격으로 한번 만들어 보자고 맘을 먹었다

목표는 완성도가 아니라 기능을 구현하면서 HTML5를 익히자는 것이므로 툴의 완성도는 기대하지 말기 바란다

CSS3 ?  Canvas ?
텍스트에 효과를 주는 방법은 많다. HTML5 관련 스펙만 봐도 CSS3 혹은 Canvas 를 이용할 수 있다
CSS의 Transform 이나 text-stroke, opacity, Gradients 등과 같은 기능만으로도 화려한 텍스트 효과처리가 가능하다. 그러나 앞서도 밝혔지만 CSS 보다는 HTML5 주요 기능을 익히는 것이 목적이므로 Canvas를 이용하기로 결정했다. Canvas를 이용해도 텍스트 크기, 그라디에이션, 색상, 폰트, 그림자, 투명도 등 처리가 가능하다
게다가 Canvas의 내용을 이미지로 변환할 수 있으니 더욱 적합하다는 생각을 하게 되었다


데모 실행
코드를 보기 전에 먼저 데모 실행화면을 살펴 보자


하단 텍스트상자에 글자를 입력하면 상단의 캔버스에 표시되며 몇 가지 텍스트 효과를 줄 수 있다
이 모든 텍스트 효과처리는 HTML5 Canvas 관련 기능을 이용한 것이며 캔버스의 최종 결과를 이미지로 변환시켜 주는 기능이 지원된다. 텍스트상자에 글이 입력되거나 삭제될 때 바로바로 그 내용이 캔버스로 반영되며 텍스트 효과도 즉시 적용되어 캔버스에 나타난다.

참고로 텍스트 효과는 데모에 적용된 기능 이외에도 그림자 효과, 그라디에이션 효과 등 더 다양한 처리가 가능하지만 데모에서는 기본적인 효과만 집중했음을 밝힌다

IE8 이전 버전을 제외한 크롬, 사파리, 오페라에서 실행 가능하며, 다음의 주소에서 확인할 수 있다
http://mkexdev.net/m/textToImageByCanvas.html


구현 하기
전체 코드를 보기 전에 몇 가지 핵심적인 내용을 살펴 보자

자바스크립트 키 관련 이벤트
HTML5 Canvas API 설명전에 먼저 자바스크립트의 키 관련 이벤트를 짚고 넘어가자
자바스크립트에는 키보드 입력과 관련된 총 3개의 이벤트가 제공된다.

keydown, keyup, keypress 가 그것인데 이들 이벤트는 키 입력에 반응하는 것이 조금씩 다르다
keydown 과 keyup 은 유사하지만하지만 keypress 는 이 둘과 약간 차이가 있는데 데모 제작과 관련해 주목해야 할 것은 keypress 는 백스페이스키(<-) 에 반응하지 않는다는 것이다.

그리고 keydown 과 keyup 의 경우 이벤트로 넘겨진 keyCode 에는 영문 대/소문자를 구분하지 않고 모두 대문자로 취급한다는 것이다. 제작하고자 하는 데모는 대/소문자를 구분해야 하며 백스페이스키로 글자를 삭제해야 하기 때문에 하나의 이벤트로 만족할 수 없었다. 즉 keypress 이벤트로 문자 입력을 처리하고 keyup으로 백스페이스와 Delete키에 반응하도록 처리했다는 것을 먼저 알린다

아래 코드와 같이 두 이벤트를 동시에 정의해서 문자 키 입력에 두 이벤트가 반응하지만, 백스페이스와 Delete 키 등의 특수키에는 keyup 이벤트만 반응한다. keyup 이벤트는 일반 문자 입력은 무시하도록 처리한다.
<input type="text" id="myText" size="60" onkeypress="inputText(event.keyCode);"   onkeyup="inputBackSpace(event.keyCode);">


캔버스 지우기
캔버스의 내용을 모두 지우기 위해서는 몇 가지 방법이 있지만,
기본적으로 캔버스의 너비 혹은 높이 정보를 다시 설정하면 캔버스내용이 모두 지워진다고 알려져 있다
canvas.width = canvas.width;

그러나 이 방법은 현재 사파리와 파이어폭스에서만 정상 동작한다
브라우저마다 HTML5 지원 현황이 달라서 발생하는 문제로 보인다.따라서 모든 브라우저에서 동작하도록 하려면 clearRect 로 캔버스 내용을 명시적으로 지워줘야 한다

아래 코드와 같이 (0,0) 부터 캔버스의 너비,높이만큼이 사각형 영역을 지움으로써 캔버스를 초기화 할 수 있다
context.clearRect(0,0,canvas.width, canvas.height);


캔버스에 텍스트 그리는 방법
Canvas의 2D Context 를 통해 각종 그리기 작업을 할 수 있는데 텍스트의 경우 fillText 와 strokeText 메서드를 통해 그릴 수 있다. fillText는 속이 찬 텍스트, strokeText는 테두리만 있는 텍스트를 그릴 수 있다

데모에서는 텍스트상자에 글자가 입력될 때 마다 바로바로 캔버스에 그리기를 수행하는데,
이때 입력된 글자 하나씩 캔버스에 그리는 방법과 캔버스를 지우고 텍스트상자에 지금까지 입력된 전체 내용을 다시 그리는 방법 중 하나를 택해야 한다

전자의 경우 텍스트가 입력되는 위치를 직접 지정해 줘야 하기 때문에 조금 복잡하며 후자의 경우 매번 캔버스를 지우고 다시 그리는 작업을 해 줘야 하기 때문에 조금 비효율적이다

따라서 데모에서는 전자의 경우처럼 텍스트 입력 시 마다 글자 하나씩 캔버스에 입력하기로 했으며 이때 알아야 하는 입력 위치는 다음과 같이 measureText 메서드를 통해 전체 문자열의 길이를 구함으로써 해결하였다
(텍스트 상자가 멀티라인을 지원하지 않기 때문에 Y 좌표는 필요치 않다)
var textWidth = context.measureText(text).width;
context.fillText(text, textWidth  , 0);  //글자가 위치할 캔버스 X 좌표를 설정한다

다만 백스페이스키(<-)와 Delete 키를 눌렀을 때 글자가 지워지는 것은 심플한 처리를 위해,캔버스 내용을 지우고 다시 입력하는 후자의 방식을 따르기로 했다.
(글자 지우기 역시 clearRect 를 통해 정해진 글자 영역만 지울 수 있지만 이 경우 x 좌표의 변화와 폰트 크기에 따른 clearRect 크기 변경 등 신경 쓸 부분이 많아 오히려 버그 유발 요인이 될 수 있어 사용을 피하기로 했다)
context.clearRect(0,0,canvas.width, canvas.height);  //캔버스를 지우고
context.fillText(text, 0, 0);                                    //다시 전체 글자를 그린다


그리고 텍스트에 폰트, 색상과 같은 효과 처리는 2D Context의 속성들을 통해 이뤄지는데 이미 입력된 내용은 반영되지 않기 때문에 이때도 역시 캔버스를 지우고 다시 그리는 방식을 취한다 


기타 살펴볼 내용
캔버스를 통한 텍스트 효과 처리시 다음의 주요 코드가 이용 되었다

: context.textBaseline = "top"
 캔버스에 텍스트가 위치하는 수평 기준선을 top 으로 해 줌으로써  글자가 기준선 아래로 표시되도록 한다

: context.font = "20px  'Tahoma'"
font 속성을 통해 캔버스에 표시될 텍스트 폰트를 처리하는데 css 의 폰트 속성과 같이 정의할 수 있다

: context.fillStyle = "red"   , context.strokeStyle
fillStyle 속성을 통해 채우기 스타일을 지정할 수 있다. 기본은 검정이다. strokeStyle 속성은 선의 색상을 지정하는데 이용한다

: String.fromCharCode(keyCode)
HTML5 , Canvas와는 무관하지만 데모에서는 유용하다. 키 이벤트로 넘여온 keyCode 를 문자로 변환해 주는 자바스크립트 내장 함수이다. 한 글자씩 입력 할 경우 필요하다

: 캔버스 내용을 이미지로 변환하기
이미 살펴본 내용이다. 캔버스의 toDataURL 메서드를 통해 이미지데이터문자열을 기반으로 이미지객체를 생성한다. [HTML5 실습] Canvas에 그린 그림을 이미지로 만들기

이것으로 구현을 위한 핵심적인 내용을 대략 살표 보았다. 이제 전체 코드를 제시한다
전체 코드는 http://mkexdev.net/m/textToImageByCanvas.html 의 소스보기를 통해서도 볼 수 있다

<!DOCTYPE html>
<html>
<head></head>
<body>
  <form name="myForm">
  <canvas id="cv" width="400" height="70" style="position: relative; border: 1px solid #000;"></canvas> 
  <button onclick="clearCanvas()">Clear</button>
  <input type="button" onclick="convertImage()" value="이미지로변환">
  <img id="myImage">
  <br>   
  <input type="radio" name="isFill" value="Fill" onchange="chkFill();" checked>Fill
  <input type="radio" name="isFill" value="Stroke" onchange="chkFill();">Stroke
  <br> 
  Font: <input id="fontSize" type="range" min="10" max="60" step="5" value="50" onchange="changeFont();" />
        <select id="fontFace" onchange="changeFont();">
         <option value="Tahoma" selected>Tahoma</option>
         <option value="Verdana">Verdana</option>
         <option value="Gulim">Gulim</option>
         <option value="Georgia">Georgia</option>
         <option value="Symbol">Symbol</option>
         <option value="Terminal">Terminal</option>
        </select>
  <br>
  Fill Color: <select id="fontColor" onchange="changeColor(1);">
         <option value="Black" selected>Black</option>
         <option value="Red">Red</option>
         <option value="Blue">Blue</option>
         <option value="Green">Green</option>
         <option value="Yellow">Yellow</option>
        </select>
  Stroke Color: <select id="strokeColor" onchange="changeColor(2);">
         <option value="Black" selected>Black</option>
         <option value="Red">Red</option>
         <option value="Blue">Blue</option>
         <option value="Green">Green</option>
         <option value="Yellow">Yellow</option>
        </select>
  <p>
  <input type="text" id="myText" size="60" onkeypress="inputText(event.keyCode);" onkeyup="inputBackSpace(event.keyCode);">
  <div id="msgDiv"></div> 
  </form>
</body>
</html>
<script type="text/javascript">
if(window.addEventListener){
    window.addEventListener('load', Init, false);
}
var canvas, context, myText,msgDiv
var isFill = true;
function Init() {    
  canvas = document.getElementById('cv');
  context = canvas.getContext('2d');    
  context.font = eval("'"+ document.getElementById('fontSize').value +'px '+ document.getElementById('fontFace').value+"'");   
  context.textBaseline = "top";  
  myText = document.getElementById('myText');
  myText.focus(); 
  msgDiv = document.getElementById("msgDiv"); 
}
function inputText(keyCode){   
  msgDiv.innerText = keyCode;    
 
  //글자의 가로위치를 구하기 위해 현재 입력된 문자열의 너비를 구한다
  var textWidth = context.measureText(myText.value).width;     
  drawText(String.fromCharCode(keyCode), textWidth);     
}    
function inputBackSpace(keyCode){
  if(keyCode == 8 || keyCode == 46){ //백스페이스 키와 Delete키를 받기 위한 함수
    clearCanvas();
    drawText(myText.value,0);    
  }
}
function drawText(text, posX){ 
  if(!isFill){ context.strokeText(text, posX  , 0); }
  else{ context.fillText(text, posX  , 0); }
}
function chkFill(){
  isFill = myForm.isFill[0].checked;
  clearCanvas();
  drawText(myText.value,0);
}
function changeFont(){
  clearCanvas();
  context.font = eval("'"+ document.getElementById('fontSize').value +'px '+ document.getElementById('fontFace').value+"'");
  drawText(myText.value,0); 
}
function changeColor(flag){
  clearCanvas();
  if(flag == 1){
    context.fillStyle = document.getElementById('fontColor').value;
  }
  else{
   context.strokeStyle = document.getElementById('strokeColor').value;
 }
 drawText(myText.value,0); 
}
function clearCanvas(){
   //canvas.width = canvas.width;   //사파리, 파폭에서만 동작(크롬, 오페라 X)    
   context.clearRect(0,0,canvas.width, canvas.height);  
}
function convertImage(){
  var image = new Image();
  var myImage = document.getElementById('myImage');
  myImage.src = canvas.toDataURL();
}
</script>


HTML5 Canvas+Text Example
한참 삘(feel) 받아서 데모를 제작하다가 이 사이트를 알게 되었다
=> http://whatdo.net/html5/example/#2

내가 구현하고자 했던 대부분의 기능이 제공되고 있었다.
사실 데모의 완성도를 꽤 올리고자 맘 먹고 시도하던 도중에 이 사이트를 보게 되었고 동기가 한풀 꺽였다
이미 제공되고 있는 사이트가 있으니 내가 만들고자 하는데모에 새로움은 별로 없기에 받았던 삘(feel)이 사그러져 버렸다 ㅎㅎ. 그래서 적당한 선에서 데모 제작을 완료하고 포스팅 하게 된 것이다

이 사이트를 보면 조금은 다른 방식으로 구현하고 있지만 더 많은 canvas 기능이 활용되었고 구현 방식 역시 배울점이 많아 보인다. 소스보기를 통해 분석해 보면 많은 도움을 얻게 될 것이니 반드시 참고 바란다

Tags Canvas, html5

submit
HTML5, Canvas 에는 그려진 내용을 URL 문자열로 반환해 주는 함수가 제공된다

Canvas 객체의 toDataURL() 함수를 통해 캔버스에 그린 그림을 문자열 형태로 변환할 수 있는데,
이 문자열에는 이미지 MIME 타입과 인코딩 방법 그리고 인코딩 된 이미지 데이터 문자열이 포함된다

대략 다음과 같은 모습이다
https://t1.daumcdn.net/cfile/tistory/226CDB4956E6D5F802"FONT-FAMILY: Tahoma">그럼, 실제 Canvas 내용이 문자열로 변환된 것을 확인해 보자
아래 그림은 Canvas에 적당히 그림을 그리고 toDataURL() 함수를 이용해 URL문자열을 띄워 본 것이다


toDataURL() 로 반환된 것이 문자열이라는 것은 다음과 같이 타입조사를 해 보면 알 수 있다
alert(typeof canvas.toDataURL()); //string 이 출력됨

이 문자열은 Canvas에 그려진 내용을 Data URL로 변환한 것이기 때문에 그 자체로 이미지 정보가 된다

따라서 이 문자열을 이미지 객체에 바인딩하거나 다른 이미지로 생성할 수 있게 된다

Canvas 에 그린 그림을 이미지로 변환하기
한 가지 간단한 샘플을 만들어 보자.
Canvas 로 그린 내용을 문자열로 변환하여 img 요소의 src 로 사용하는 것이다
Canvas 에 그리기 작업을 수행하는 코드는 이전 글인 [HTML5] Canvas '마무로 데모' 코드를 이용하므로 구현 코드는 생략하도록 한다. 이 글에서는 Canvas 결과를 이미지 소스로 바인딩하는 것을 제시한다

다음 코드와 같이 Canvas와 버턴, 그리고 img 요소를 정의한다
Canvas에 그림을 그리고 버턴을 클릭하면 오른쪽 img 요소에 그 내용이 이미지 소스로 활용되는 예이다

<canvas id="drawCanvas" width="200" height="200" style=" position: relative; border: 1px solid #000;"></canvas>
<button onclick="toDataURL();">이미지로 변환=></button>     
<img id="myImage">
.....
<script type="text/javascript">
function toDataURL(){
  var myImage = document.getElementById('myImage');
  myImage.src = canvas.toDataURL();
}
</script>

데모를 실행하고 캔버스에 적당히 그림을 그린 후 이미지 변환을 클릭하면 오른쪽에 이미지가 표시된다
이렇게 생성된 이미지는 완전한 하나의 이미지 객체 이므로 로컬에 이미지로 저장하는 등의 이미지 작업이 가능하다


참고로 이렇게 생성된 이미지의 HTML 코드는 아래와 같다



Canvas 에 그린 그림을 다른 Canvas 로 복사하기
이번에는 Canvas에 그린 내용을 다른 Canvas로 옮기는 즉 복사하는 예를 살펴보자.
복사 방법이야 여러 가지가 있을 수 있겠지만 여기서는 toDataURL() 함수로 반환된 이미지데이터문자열을 이용해서 복사하는 방법을 알아보자

언뜻 생각하기에 toDataURL() 함수가 있다면 fromDataURL() 함수가 있지 않을까 생각이 든다
다시말해 캔버스 내용을 URL 문자열로 반환해 주는 함수가 있다면 역으로 URL 문자열을 캔버스 내용으로 사용할 수 있는 함수 말이다. 그런데 찾아 보니 그런 함수는 없어 보인다. 아쉬운 부분이다

그렇다면 우리가 직접 fromDataURL 함수를 만들어 보기로 하자
아래 코드와 같이 두 개의 Canvas를 정의하고 왼쪽 캔버스의 내용을 오른쪽 캔버스로 복사하기 위해 toDataURL()로 얻어진 문자열을 이미지 객체의 소스로 바인딩하고 이미지가 로딩될 때 복사 대상 캔버스의 drawImage 함수를 이용해 이미지를 그리는 로직이다.
<canvas id="drawCanvas" width="200" height="200" style=" position: relative; border: 1px solid #000;"></canvas>
<button onclick="fromDataURL();">캔버스 복사=></button>                  
<canvas id="copyCanvas" width="200" height="200" style=" position: relative; border: 1px solid #000;"></canvas>
...
<script type="text/javascript">
function fromDataURL(){       
  var copyCanvas = document.getElementById('copyCanvas');    
  var copyContext = copyCanvas.getContext('2d'); 
 
  var image = new Image();
  image.src = canvas.toDataURL(); 
 
  image.onload = function(){
    copyContext.drawImage(image,0,0);
  } 
}
</script>


데모를 실행한 결과 화면은 아래와 같다


어떻게 보면 fromDataURL() 함수는 끼워 맞춘 듯한 느낌이다
하지만 toDataURL()로 얻어진 이미지데이터문자열을 이런 형태로도 이용할 수 있다는 힌트만 가지면 되겠다

2010.11.24 추가>>
위에서, Canvas 그림을 다른 Canvas로 복사할 때 이미지객체를 생성하는 단계가 있었다
확인 해 보니, 이미지객체를 경유하지 않고 대상 Canvas에 원본 Canvas를 drawImage 해 주면 된다
따라서 단지 복사가 목적이라면 중간 경유로 사용된 이미지객체의 생성은 불필요 하겠다

fromDataURL 함수는 아래와 같이 수정하면 된다
function fromDataURL(){       
  var copyCanvas = document.getElementById('copyCanvas');    
  var copyContext = copyCanvas.getContext('2d'); 
  copyContext.drawImage(canvas,0,0);  
}


Canvas 내용을 문자열로 얻을 수 있다는 것은...
웹에서 다양한 시나리오를 구현할 수 있다는 의미가 된다
글에서 알아본 것과 같이 캔버스 내용을 이미지로 변환하여 로컬 컴퓨터에 저장할 수 있으며
또 다른 예로 캔버스 내용을 서버로 업로드 하여 다른 사람과 공유하거나 관리할 수 있게 된다
또한 캔버스 내용을 쿠키나 localStorage 등에 저장하여 계속 사용할 수 있으며 페이지 통신을 통해 두 페이지간 캔버스 내용을 교환할 수도 있다. 

결론적으로  문자열로 처리 가능한 모든 시나리오에 캔버스를 이용할 수 있다는 의미가 된다
다만 이렇게 생성한 이미지는 일반 이미지 파일과는 달리 브라우저에 캐시되지 않기 때문에
쇼핑몰 이미지 리스트와 같은 많은 이미지를 서버에서 불러와 캐시되는 시나리오에는 적합하지 않을 수 있다

자신만의 다양한 시나리오를 구상해 실현해 보기 바란다

....

참고로 toDataURL() 함수는 두개의 매개변수를 가지는데, 첫번째 인수는 이미지MIME 타입을 지정하는데 이용되며 나머지 인수는 이미지 품질 정도와 같은 추가 이미지 효과를 지정하는데 사용된다
이전 샘플과 같이 매개변수 없이 호출하게 되면 기본적으로 image/png 타입으로 설정된다
만일 jpeg 를 원한다면 다음의 코드가 가능하다

canvas.toDataURL("image/jpeg");

그러나 테스트를 해 보니 브라우저별로 지원되는 부분이 조금씩 다르니 참고하기 바란다

toDataURL 에 대한 더 자세한 내용은 다음의 W3C 스펙 설명을 확인 하자
http://dev.w3.org/html5/canvas-api/canvas-2d-api.html#todataurl-method
Tags Canvas, html5

submit

W3C, HTML5 도입 이르다?

Posted in 모바일/HTML5 // Posted at 2010. 10. 8. 11:51

오늘 연속적으로 기사만 두 건 포스팅하네..
W3C가 HTML5 행보에 찬물을 끼얹는 발언을 했구나!
이건 뭐.. 주최측이라고는 하지만.. 달라도 너무 다른거 아닌가...

기사원문: W3C "HTML5, 도입 이르다"... 브라우저 업체와 노선차이

사실 현재시점에 어느 누가 HTML5를 전면 도입 가능하다고 생각하고 있을까?

Mark Pilgrim 이 언급했듯이 HTML5는 한 덩어리의 기술이 아니다
HTML5는 여러 기술 스펙의 조합이며 최신 브라우저에서는 이미 많은 부분 적용되어 있는것이 현실이다

물론 아직 표준화가 완료되지 않아서 브라우저간 조금씩 상이한 구현과 향후 변경 가능성을 내포하고 있어 불완전하다는 측면은 분명 존재한다.

W3C의 발언이 이런 우려를 내비친 보수적인 입장이라는 점은 이해하지만 표준화를 주도하는 입장에서 굳이 이런 발언을 할 필요가 있나 싶다. HTML5 의 가능성과 빠른 표준화를 공표하고 그사이 발생할 수 있는 호환성 문제를 조심스레 제기하는 수준이라면 모를까... 마치 찬물을 끼얹는 듯한 발언에 아쉬움이 든다

기사 중 다음의 글에 공감한다

일부 웹 전문가들은 기술이 표준화되기 이전에 이미 업계에 널리 확산돼 실용성을 검증받는 과정이 자연스러운 수순이라는 입장이다

 

Tags html5

submit

Aptana, HTML5를 지원하는 웹 개발 툴

Posted in 모바일/HTML5 // Posted at 2010. 10. 4. 13:50

마이크로소프트의 닷넷을 기반으로 웹 응용프로그램을 개발할 땐 비주얼스튜디오만 있으면 된다
개인적으로 MS 진영의 개발툴은 그 어떤 것보다 강력하다고 생각한다
(완벽에 가까운 한글 지원을 포함하여...)

윈도우 응용프로그램, 웹 응용프로그램, 웹 서비스, 라이브러리 등 닷넷과 관련한 모든 개발은 비주얼스튜디오 하나로 다 해결할 수 있다. 물론 ASP.NET 기반의 웹 개발을 위한 도구인 Visual Web Developer 가 존재하지만 이것은 통합 개발환경인 비주얼스튜디오의 서브도구 개념이기 때문에 특수한 경우가 아니라면 비주얼스튜디오만으로도 충분하다.

그리고 과거 ASP나 PHP로 웹 사이트를 개발할 때 특별한 툴을 이용하지는 않았다
한때 asp개발을 위해 비주얼인터데브를 사용한 적이 있으나 프로그래밍 모델이 복잡하지 않은 asp 개발에 오히려 복잡성을 증가시키는 것 같아 Acroedit
와 같은 심플한 텍스트 에디터를 사용했었다
(Acroedit 는 필자가 거의 10년 가까이 사용하고 있는 애착(?)이 가는 무료 에디터이다)
그리고 간혹 웹 디자이너나 퍼블리셔들이 사용하던 드림위버(혹은 나모웹에디터) 라는 툴도 듬성듬성 사용했었다

그러나 요즘 HTML5 기반 응용프로그램을 개발하려다 보니 개발툴의 절실함을 많이 느낀다
Acroedit 는 웹 개발을 위해 FTP 기능, 언어 예약어 하이라이트 기능, 책갈피 기능 등 에디터로써 유용한 기능들이 많이 포함되어 있지만 비주얼스튜디오와 같은 인텔리전스 기능은 가지고 있지 않다

HTML5 개발은 HTML 태그와 더불어 자바스크립트를 사용하는 경우가 많기 때문에 언어 하이라이트는 필수라 할 수 있으며 객체에 정의되어 있는 함수나 속성을 자동으로 띄워주는 인텔리전스 기능이 매우 목마르다. 물론 HTML5 이전의 웹 개발환경에도 자바스크립트의 비중이 적다고는 할 수 없지만 개인적으로 그 당시에는 클라이언트 스크립트를 요즘과 같이 관심있게 들여다 본적이 없었기 때문에 필요성도 덜 느꼈었다.

이번에 소개할 Aptana 는 웹, 특히 자바스크립트나 HTML, CSS와 같은 클라이언트 단 웹 개발을 돕는 개발 툴로 이미 꽤 유명세를 타고 있는 툴인 것 같다

나의 경우 HTML5, CSS3 에 관심을 두기 시작하면서 알게 된 툴이다
툴을 직접 깔아보니 자바 개발툴인 이클립스와 매우 유사한 UI 및 프로세스를 지니고 있다
알고 보니 이클립스를 통해 웹 개발을 돕는 플러그인 형태로 제공되던 툴인데 현재 독립 실행형으로도 배포되고 있는 듯 하다

Aptana Studio 버전 3 부터는 HTML5, CSS3 를 지원하며 현재 베타버전으로 다음의 링크를 통해 다운받을 수 있다 => http://aptana.com/products/studio3



위 그림과 같이 HTML5 태그가 지원되며 브라우저 지원현황도 자동으로 나타내 준다

아직 상세한 기능이나 구체적 사용법은 숙지되지 않은 상태라 더 자세한 정보를 알려 줄수는 없지만 웹 클라이언트 단 개발에 있어 매우 유용한 툴으로 가치가 있어 보인다

언젠가 본격적으로 사용하게 될 도구 목록에 추가해 두기로한다

참고로 Aptana 에 대해 소개한 다음의 블로그를 참고 바란다
http://firejune.com/1205
http://firejune.com/1581

Tags aptana, html5

submit

듣기로 현재(2010.09.30) W3C의 HTML5 표준화 프로세스는 Working Draft 단계에 있는 것으로 알고 있다. 2009년 10월에 WHATWG 에 의해 Last Call이 선언되어 W3C로 사양이 제출되었다
이제 W3C에서도 Last Call 프로세스를 진행하기로 했다는 소식이다

Last Call 은 표준을 위한 권고안이 되기 전에 최종 검토하는 기간이다
ETRI 이원석님의 블로그에 향후 일정이 상세히 설명되어 있으니 참고 바란다
=> W3C, HTML5 표준 초안 Last Call 예정

글에 따르면 2011년 5월에 Last Call 이 종료된다고 한다
이후 권고 후보, 권고안, 권고 과정을 거치면 드디어 표준화가 완성된다

사실 권고안만 되면 거의 게임 끝났다고 볼 수 있다
한 때 HTML5 의 표준화 완성이나 보편화가 최소 10년 후, 먼 미래가 될 것이라는 일부 부정적 시각이 있었으나 현재 분위기로 봐서는 2012년 정도에는 뚜렷한 윤곽이 나오지 않을까 싶다

Tags html5

submit

[HTML5] Web Socket (웹 소켓)

Posted in 모바일/HTML5 // Posted at 2010. 9. 30. 13:44

실시간 (양방향) 통신을 위한 웹의 노력
개인적인 생각으로 HTML5의 새로운 스펙중에 사용자가 가장 흥미로워 한 것이 Canvas 라면

개발자가 가장 흥미로워 한 것은 바로 웹 소켓(Web Socket)이지 않나 싶다

필자 역시 순수 웹 환경에서 연결 지향 양방향 통신을 지원하는 웹 소켓이 가장 눈에 띄는 것 중 하나였다. 과거 순수 웹 환경에서 채팅과 같은 실시간 응용프로그램을 위한 얼마나 많은 시도들이 있었던가...

이제 박물관(?)에서나 볼 법한 숨긴 frame(or iframe) 을 통한 반복적인 재요청은 당시만 해도 웹에서 실시간 효과를 낼 수 있는 참신한 아이디어로 부상한 적이 있었다

이후 Ajax의 등장으로 비동기로 반복 요청을 할 수 있어 그나마 조금은 개선 되었다
그러나 여전히 클라이언트의 비 효율적인 재요청을 피할 수는 없었다

그리고 이후 Comet 의 등장으로 서버 데이터 수신 후 재 요청이 가능해져 불필요한 반복 요청의 비효율성은 개선되었다.

그러나 이 모든 것은 '폴링(polling)' 방식이다
즉 데이터 수신을 위해 서버가 클라이언트에게 전송해 주는 푸시(push)방식이 아니라 클라이언트가 서버에에게 요청하는 폴링(polling) 방식이었다

비교적 최적의 대안이었던 Comet 역시 무의미한 반복 요청을 피하기 위한 연결유지 기법이 적용되었지만 일정 시간 이후에는 연결을 종료하고 다시 연결해야 한다. 그래서 Comet을 Long-Polling 라 한다

참고: [HTML5] Server-Sent Events

웹의 진정한 실시간 (양방향) 통신, 웹 소켓(Web Socket)의 등장
초기 웹의 탄생 목적은 문서 전달과 하이퍼링크를 통한 문서 연결이었다
웹을 위한 HTTP 프로토콜은 이러한 목적에 매우 부합하는 모델이다
그러나 시대가 변하고 환경이 발전할 수록 웹이 더 이상 문서공유에만 집중할 수 없었다
갈수록 동적인 표현과 뛰어난 상호작용이 요구되었고 이로 인해 여러 새로운 기술이 탄생되었다

플래시(플렉스), 자바애플릿(자바FX), ActiveX , 실버라이트 등을 들 수 있다
하지만 이들은 웹에서 화려한 동작과 뛰어난 상호작용을 보장하지만 순수 웹 환경이 아니라 별도의 런타임을 플러그 인 형태로 브라우저에 설치해야 사용 가능하다

HTML5는 그 주요 목적 중 하나인, 플러그 인 없는 일관되고 표준화된 웹 응용 환경이라는 기치하에 많은 참신한 스펙들이 개발되었다.

그 중 순수 웹 환경에서 실시간 양방향 통신을 위한 스펙이 바로 '웹 소켓(Web Socket)' 이다
웹 소켓은 웹 서버와 웹 브라우저가 지속적으로 연결된 TCP 라인을 통해 실시간으로 데이터를 주고 받을 수 있도록 하는 HTML5의 새로운 사양이다. 따라서 웹 소켓을 이용하면 일반적인 TCP소켓과 같이 연결지향 양방향 전이중 통신이 가능하다

이와 같은 특징으로 웹에서도 채팅이나 게임, 실시간 주식 차트와 같은 실시간이 요구되는 응용프로그램의 개발을 한층 효과적으로 구현할 수 있게 되었다

웹 소켓과 Ajax 속도 비교
한 일본 사이트에서 웹 소켓과 (Ajax의 통신 객체인) XMLHttpRequest 의 속도 비교를 확인할 수 있는 페이지를 제공하고 있어 화제가 되고 있다
=> http://bloga.jp/ws/jq/wakachi/mecab/wakachi.html (크롬 or 사파리에서 실행)


서버에 존재하는 1,981(공백포함) 길이의 일본문자를 132개로 끊어서 가져오는 데모인데, 각각 웹 소켓과 여러개의 Ajax(병렬 Ajax)를 이용해 각각 호출해서 실행 속도를 비교했다

테스트 할 때마다 실행 속도의 차이가 조금씩 나지만 웹 소켓이 대략 50배 이상 좋은 성능을 보이고 있다


물론 이 사이트의 테스트 시나리오에 따르면, 한번에 모든 문자를 가져오는 것이 아니라 132개로 나눠진 단락들을 가져오는 것이다 보니 한번 연결된 통신 라인으로 데이터만 가져오는 웹 소켓에 비해 매번 헤더정보를 실어서 새로 요청 하는 Ajax가 더욱 느리게 느껴질 수 있다

하지만 이것은 '수 차례 송/수신을 하는 시나리오' 를 가정한 만큼 테스트 시나리오에 문제 제기를 할 필요는 없어 보인다. 웹 소켓을 사용하는 환경의 거의 대부분이 이런 시나리오이기 때문에 더욱 그렇다

어쨋던 확실히 실시간 통신환경에서는 Ajax 보다는 웹 소켓이 월등하다는 것을 알 수 있다

웹 소켓이 필요한 다섯가지 징후?
Peter Lubbers 라는 개발자가 'Five Signs You Need HTML5 WebSockets' 이라는 글을 포스팅 했다
HTML5의 웹 소켓을 이용하면 좋을 5가지 경우를 조목조목 설명하고 있다
뭐.. 결론은 웹 소켓 좋다는 거다 ^^ . 글에서 상단의 Summary 만 가져와 본다

  1. Your web application has data that must flow bi-directional simultaneously.
  2. Your web application must scale to large numbers of concurrent users.
  3. Your web application must extend TCP-based protocols to the browser.
  4. Your web application developers need an API that is easy to use.
  5. Your web application must extend SOA over the Web and in the Cloud.

대략 난잡번역 해 보면,
1. 실시간 양방향 데이터 통신이 필요한 경우
2. 많은 수의 동시 접속자를 수용해야 하는 경우
3. 브라우저에서 TCP 기반의 통신으로 확장해야 하는 경우
4. 개발자에게 사용하기 쉬운 API가 필요할 경우
5. 클라우드 환경이나 웹을 넘어 SOA 로 확장해야 하는 경우

그리고 각 경우에 대한 설명이 자세히 나열되어 있으니 스스로 번역해서 음미 바란다
(누가 좀 안해주나 ^^;)


지원되는 브라우저 현황
IE와 오페라를 제외한 사파리,크롬,파이어폭스 최신버전에서 웹 소켓을 지원한다


그림1. 브라우저별 Web Sockeet 지원 현황 (출처: http://caniuse.com/)


웹 소켓 구현하기
웹 소켓 역시 일반적인 TCP 소켓 통신처럼 웹 소켓 역시 서버와 클라이언트간 데이터 교환이 이루어지는 형태이다. 따라서 다른 HTML5 스펙과는 달리 클라이언트 코드만으로 실행 가능한 예를 만들 수는 없다

즉 클라이언트에서는 웹 소켓이 제공하는 자바스크립트 API를 이용해 서버에 연결하고 데이터를 송/수신하는 코드를 구현해야 하며 서버에서는 웹 소켓 프로토콜에 맞는 전용 장치가 구축되어 있어야 한다

웹 소켓 클라이언트
웹 소켓이 제공하는 클라이언트 측 API는 매우 심플하다. 기본적인 서버 연결, 데이터 송신, 데이터 수신만 정의하면 나머지는 일반적인 스크립트 로직일 뿐이다

: 서버연결

웹 소켓이 동작하기 위해서 제일 처음 서버와 연결이 되어야 한다. HTML5가 제공하는 WebSocket 객체를 통해 서버 연결을 수행한다. 일반 통신은 ws, 보안 통신은 wss 프로토콜을 이용한다
기본 포트 역시 http,https와 동일한 80,443을 이용한다
var wSocket = new WebSocket("ws://yourdomain/demo");

: 데이터 송신
서버와 연결이 되면 이제부터 데이터를 주고 받을 수 있게 된다. WebSocket 객체의 send 함수로 데이터를 서버로 송신할 수 있다
wSocket.send("송신 메시지");

: 데이터 수신
서버에서 푸시(전송)하는 데이터를 받으려면 message 이벤트를 구현하면 된다
wSocket.onmessage function(e){ //매개변수 e를 통해 수신된 데이터를 조회할 수 있다 

클라이언트 API는 이 세가지가 핵심이다. 추가로 아래와 같은 이벤트도 제공된다
- open 이벤트: 연결이 설정되면 발생
- close 이벤트: 연결이 끊어지면 발생

웹 소켓을 이용하는 클라이언트 코드의 전체 모습은 대략 다음과 같다

<script>
  var wSocket = new WebSocket("ws:yourdomain/demo");
 
  wSocket.onmessage = function(e){  alert(e.data);  }  

  wSocket.onopen = function(e){ alert("서버 연결 완료"); } 
  wSocket.onclose = function(e){ alert("서버 연결 종료"); }  

  function send(){ //서버로 데이터를 전송하는 메서드
    wSocket.send("Hello");
  }
</script>

보는 바와 같이, 소켓 통신을 위한 클라이언트 측 코드는 매우 심플하며 직관적이다. 하지만 말했듯이 클라이언트 코드 만으로 데모는 실행되지 않는다. 클라이언트와 통신하는 서버가 존재해야 하는데 아래에 계속 이어진다

웹 소켓 서버
웹 소켓은 일반적인 TCP 소켓과는 다른 프로토콜로 설계되었다. 따라서 기존 TCP 서버를 그대로 이용할 수 없고 새로 구현해야 하는데 웹 소켓 서버 사양에 맞도록 구현해야 한다.

웹 소켓 서버를 위한 다양한 오픈소스가 온라인에서 제공되고 있는데,
pywebsocket , phpwebsocket, jWebSocket, web-socket-ruby, Socket.IO-node 와 같은 모듈을 이용하면 웹 소켓 서버를 쉽게 구축할 수 있다

이 글에서는 jWebSocket을 이용해서 웹 소켓 서버를 구축하고 제공되는 데모를 실행해 보도록 하자

jWebSocket 라이브러리는 http://jwebsocket.org/
 사이트를 통해 다운로드 받을 수 있는데
자바로 구현된 웹 소켓 서버모듈인 jWebSocketServer와 자바스크립트로 구현된 웹 소켓 클라이언트 데모인 jWebSocketClient 을 다운받으면 된다. 참고로 jWebSocket 라이브러리의 전체 소스코드는 jWebSocketFullSource를 다운받아 볼 수 있다

jWebSocketServer 구동
우선 웹 소켓 서버를 구동 시켜야 하는데, 아파치 웹서버나 톰켓을 이용하여 구동하거나 Stand-Alone 으로도 구동시킬 수 있다. 이 글에서는 간단한 테스트를 위해 Stand-Alone로 구동시켜 보도록 하자

jWebSocketServer 가 자바로 구현되었기 때문에 자바 가상 머신이 설치되어 있어야 한다
서버에 최소 1.5 버전 이상의 자바런타임을 설치하도록 하자
그리고 기본적인 자바 환경 변수인 JAVA_HOME 과 java.exe를 Path에 등록한다

이제 자바를 위한 기본 설정이 마무리 되었으니 jWebSocketServer를 구동시키면 된다
Stand-Alone로 구동시키기 때문에 별도의 웹 서버는 필요하지 않고 배치파일을 실행하는 것으로 대신할 수 있다. 다운받는 jWebSocketServer을 압축해제 하고 bin 폴더에 있는 jWebSocketServer.bat 파일을 명령프롬프트에서 실행하도록 하자. 배치파일을 실행하면 설정을 위한 일련의 작업들이 진행되고 최종적으로 다음과 같은 모습으로 웹 소켓 서버의 구동이 시작된다


이후 웹 소켓 서버와의 통신로그와 디버그 메세지들이 이 창에 계속 기록된다
배치파일을 실행하는 동안 서버가 구동되는 것이기 때문에 실행창을 닫으면 서버도 종료됨을 기억하자

다음의 퀵스타트를 참고 하자
http://code.google.com/p/jwebsocket/wiki/QuickStart

jWebSocketClient 데모 테스트 하기
서버가 준비되었으니 웹 소켓 통신을 수행하는 클라이언트 데모를 확인해 보자
jWebSocketClient 를 다운받아서 압축해제 하면 다양한 데모가 미리 준비되어 있다
우리는 여기서 채팅데모인 chat.htm 을 실행해 보자

웹 소켓을 지원하는 브라우저를 두 개 띄우고 chat.html을 실행한다. 아래 그림은 크롬 브라우저의 실행 모습이다. 두 개의 브라우저에서 각각 로그인 한 뒤, 채팅하는 모습이다


채팅 외에도 다양한 데모가 있으니 참고 바라며 웹 소켓서버 통신의 기술적 구현을 배우기 위해 코드를 꼼꼼히 살펴보는 것도 좋을 것이다.

참고로 jWebSocket 에서 서버 연결을 위해 다음과 같은 url을 정의하고 있다
var lURL = jws.JWS_SERVER_URL + "/;prot=json,timeout=360000";
...
JWS_SERVER_URL: "ws://" + ( self.location.hostname ? self.location.hostname : "localhost" ) + ":8787"

ws 프토토콜로 localhost, 8787포트로 연결하며 추가로 json 포맷과 타임아웃이 설정되었다

마지막으로 WebSocket 은 다른 HTML5 사양보다 프로그램적인 성격이 강하다.
특히 클라이언트 코드만으로 해결될 수 있는 것이 아니라 좀 더 복잡해 보일 수 있다.
또한 많은 수의 클라이언트를 수용하기 위해서는 소켓 서버의 성능과 가용성이 확보되어야 하기 때문에 보다 신중한 접근이 필요하다 하겠다. 글에서 소개한 웹 소켓 서버 라이브러리를 적절히 이용하거나 오픈 소스를 분석해서 내공을 키우기 바란다

2016.07.15 추가>
- Node.js기반 socket.io 라이브러리를 이용해 간단한 웹 채팅을 구현한 다음 포시팅도 참고하기 바란다.
- [NodeJS] socket.io를 활용한 웹채팅 구현



참고>

Firefox의 웹소켓(WebSocket) 기능
http://code.google.com/p/websocket-sample/
http://dev.w3.org/html5/websockets/
http://www.websockets.org/about.html
http://www.codeproject.com/KB/webservices/c_sharp_web_socket_server.aspx

submit

Visual Studio 에서 HTML5 템플릿 만들기

Posted in 모바일/HTML5 // Posted at 2010. 9. 28. 15:20
간혹 글을 쓰다 보면 카테고리를 어디에 둘지 애매할 때가 있다. 이 글이 그러하다.
이 글에서 소개하는 내용은, 마이크로스프트의 닷넷 개발툴인 Visual Studio 2010 환경에서 HTML5 개발을 편하게 하기 위한 템플릿을 제작하는 것이다

원문글의 필자와 나처럼 Visual Studio를 주로 사용하는 개발자에게는 도움이 되나 그렇지 않은 개발자에게는 도움이 되지 않을 수도 있다. 이 글은 HTML5 자체가 아니라 Visual Studio를 다루는 내용에 가깝기 때문이다. 그래서 HTML5 카테고리에 은근슬쩍 집어 넣기가 살짝 꺼려진다.
(그렇다고 이 글을 위해 VisualStudio 카테고리를 만들 수는 없지 않나)

하지만 HTML5 의 기본 문서 구조나 템플릿 구조를 포함하고 있기에 HTML5와 완전히 동떨어져 있다고만 할 수는 없다. 결국 이 글은 이 블로그의 HTML5 카테고리만큼 어울리는데도 없다는 결론이다 ㅎㅎ

원문글> How to Create HTML5 Website and Page Templates for Visual Studio 2010

제목 그대로 Visual Studio 2010 에서 HTML5 에 관한 웹사이트 템플릿과 페이지 템플릿을 만드는 방법을 소개하는 글이다. 글을 보면 알겠지만, 템플릿을 만들고 VS2010 적용하는 것 자체는 매우 간단하기때문에 쉽게 적용해 볼 수 있다.

개인적으로 이 글에서 강조하고 싶은 것은 VS2010 템플릿 제작방법이 아니라,
필자가 템플릿을 제작한 동기와 권장되는 HTML5 템플리 구조 그리고 HTML5 프로젝트의 기본 코드 구성을 강조하고 싶다

우선 필자는 VS2010 을 자주 다루는 MS 직원으로써 현재 HTML5와 JavaScript 에 꽂혀 있다고 한다
(음... 이 점은 현재의 나와 매우 유사하다고 볼 수 있다 ㅎ)

그러다보니 자연스레 VS에서 쉽게 HTML5 프로젝트를 생성하고 싶었고 그러던 찰나에
blog post by Zander Martineau 를 보고 영감을 얻어 VS용 HTML5 템플릿을 만들기로 했단다
(음.. 이 점은 나보다 낫다. 난 뭐냐.. 이런 영감도 없다뉘...)

재미있는것은 blog post by Zander Martineau 글의 필자도 HTML5 Boilerplate 로부터 코드를 참조했다고 한다. 꼬리에 꼬리를 무는 형태의 글이다. 하나의 글을 통해 세개의 유용한 정보를 취득한 셈이다

그리고 HTML 기본 코드 구성에 대해 잠시 살펴보면,
HTML5 문서임을 정의하는<!doctype html> 으로 출발하여 기본적인 meta 태그들 그리고 기본으로 깔고 있는 스타일 정의를 포함하고 있다. 또한 jQuery 라이브러리 추가를 위한 Google, MS 의 CDN 스크립트 정의, HTML5 지원여부를 판별하기 위한 Modernizr 라이브러리 정의 역시 포함하고 있다.
또한 (간혹 욕은 듣고 있지만) 여전히 HTML5 브라우저 호환성의 주요한 대안인 구글 크롬 프레임 적용을 위한 코드도 포함되어 있다

블로그 관련글: Modernizr 라이브러리  ,
  JQuery 사용 환경 설정

이러한 코드을 통해 HTML5문서가 갖추어야 할 기본적인 구성과 참조항목을 알 수 있다는 것이 주요하다. 결론적으로 VS 를 다루는 개발자들에게는 쉽게 HTML5 프로젝트를 생성하는 법을 알려 주는 유용한 정보이며 그렇지 않은 개발자들에게는 HTML5의 기본적인 코드 구성을 알려 주는 유용한 정보인 것이다

submit