지난번에 올렸던 Internet Explorer 9에 대한 인터뷰 기사에 이어서, 실질적인 IE 9.0의 모습을 살펴볼 수 있는 동영상도 같이 올려봅니다. 이 동영상은 IE 9 개발 팀이 진행하는 인터뷰이며, 전체적으로 Windows Live Mail과 GMail과 같이 자바스크립트 엔진을 극적으로 활용하는 웹 어플리케이션에서의 성능 향상이 얼마나 이루어지고 있는지를 보여줍니다.

IE 9부터는 인터넷 환경에 최적화된 자바스크립트 엔진을 직접 고안하고 개발하여 자바스크립트 기반의 웹 사이트에서 문제가 되는 속도 문제를 획기적으로 개선하고자 하는 것이 주된 취지입니다. 이 부분 만으로도, Internet Explorer로 보다 쾌적한 웹 검색 경험을 얻을 수 있을 것입니다. 그리고, 더 나아가서는 Direct 2D 엔진을 통하여 Windows Vista나 Windows 7에서 지원하는 Aero 엔진과 함께 고해상도 기반의 웹 브라우징도 경험이 가능할 것으로 보입니다.

아래 동영상을 감상하기 위해서는 Silverlight 플러그인이 필요합니다. 아래 동영상이 보이지 않을 경우, Silverlight 플러그인을 http://www.microsoft.com/silverlight 에서 설치하시거나, 브라우저 보안 설정을 확인하여 Silverlight 플러그인이 동작할 수 있도록 설정하여 주십시오. (원본 페이지: http://channel9.msdn.com/posts/Charles/IE-9-First-look-at-the-new-JS-Engine/)


크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

Visual Studio 2010 베타 2가 이 글을 쓰는 현 시점에 Express Edition과 함께 새롭게 공개되었습니다. .NET Framework 4.0과 더불어서 C# 4.0, Visual Basic .NET 10.0 등 언어들의 기능도 새롭게 향상되었으며, 특히 이목을 끄는 것은 Dynamic Language Runtime과 연동되는 Dynamic Programming에 관한 것입니다.

 

Dynamic Programming에 대해서, 철수네 소프트웨어 세상 블로그 (http://blogs.msdn.com/bkchung/)에 소개된 내용을 오래 전에 처음 포스팅을 했었지만 최근까지도 dynamic 키워드의 실용적인 사례를 찾지 못하고 있었습니다만, 최근 dynamic 키워드의 새로운 활용 가능성을 새롭게 발견하였습니다. 여러 시나리오가 있을 수 있겠지만 제가 오늘 이 포스트를 통해서 조명해보고자 하는 것은 Windows Forms가 제공하는 Web Browser와의 연동에 관한 것입니다.

 

Windows Forms가 버전 2.0에 들어서면서부터 매우 실용적인 컴포넌트를 새롭게 추가하였는데 바로 웹 브라우저 컨트롤이 그것이었습니다. 웹 브라우저 컨트롤은 단순히 브라우저로서도 활용할 수 있지만 잘 활용한다면 사용자 인터페이스를 웹 기반으로 업그레이드하는 것 또한 가능합니다.

 

하지만 COM Interop 프로그래밍에 기댈 수 밖에 없는 부분은 여전히 많았고, 당시의 C# 언어 사양만으로 COM Interop을 다루는데에는 비효율적이고 생산성이 떨어지는 부분이 많았습니다. 그런 이유로, 예전의 브라우저 컨트롤보다는 "조금 뛰어난" 수준으로 인지되는데에 그쳤습니다. 하지만 이번에 새로 소개되는 Dynamic Programming과 결합하면 매우 매력적인 프레임워크로 다시 거듭나게 됩니다.

 

Dynamic Programming을 시험해볼 좋은 자바스크립트 예제를 찾던 중, http://www.javascriptfreecode.com/34.htm 의 소스 코드를 발췌하여 Dynamic Programming 버전으로 만들어보았습니다.

 

본디 이 스크립트가 하는 일은 Internet Explorer가 고유하게 제공하는 웨이브 필터를 활용해서 텍스트를 화려하게 보일 수 있도록 치장하는 것입니다. 그러나 이 기능을, 여러 브라우저가 보는 페이지로서가 아닌, 온전히 Windows Forms 응용프로그램만을 위한 고유한 기능으로 바꾸어보도록 하겠습니다.

 

  1. 폼에 웹 브라우저 컨트롤을 새로 추가합니다.
  2. 웹 브라우저 컨트롤이 처음 보일 페이지를 about:blank 로 설정합니다. 빈 문서를 준비시키도록 하는데에 도움이 됩니다.
  3. 기본 이벤트인 DocumentCompleted 이벤트 핸들러를 새로 추가합니다.
  4. 아래의 코드를 작성합니다.

private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    dynamic document = this.webBrowser.Document.DomDocument;
    dynamic window = this.webBrowser.Document.Window.DomWindow;

    document.write(String.Format(@"
<!-- Original Source: http://www.javascriptfreecode.com/34.htm -->
<div id=""Zittertext"" style=""font-weight: bold; font-size: 25pt; filter: Wave(freq=5, light=0, phase=8, strength=1); width: 100%; color: orange;"">
<div style=""background-color: #FFFF00; text-align: center; color: black; display: inline;"">
{0}
</div>
</div>
", window.prompt("Please type a message to display: ", "Hello World!")));

    Action DynWave = () =>
    {
        dynamic filter = document.getElementById("Zittertext").filters[0];
        if (filter.freq > 130)
            filter.freq = 15;
        filter.freq++;
        if (filter.phase > 50)
            filter.phase = 1;
        filter.phase++;
        if (filter.strength > 1)
            filter.strength = .1;
        filter.strength++;
    };

    Timer timer = new Timer();
    timer.Tick += (a, b) => DynWave();
    timer.Interval = 50;
    timer.Enabled = true;
}

 

위의 코드에서 우리가 관심있게 봐두어야 할 부분은 dynamic으로 선언한 변수 뒤에 나타나는 표현식들입니다. 컴파일러 기반의 언어들은 늘 그렇듯 문법의 정확성을 언제나 따지게 됩니다. C#도 분명히 그런 언어였습니다. 하지만 Dynamic Programming을 통하여 위와 같이 컴파일 시점에는 존재하지 않는 내용을 런타임 때에 유추해낼 수 있게 되었습니다.

 

여기서 의문점이 드는 것이 있는데, 그렇다면 이를 유추해내기 위해서 어떤 식으로 구현을 제공하는가에 대한 부분입니다. 이 부분에 대한 답은 바로 .NET Framework가 런타임 과정에서 정확한 객체 정보를 확인하기 위해서 사용하는 ObjectBinder에 있습니다. regasm 유틸리티로 등록해두었던 COM Interop Assembly나 Primary Interop Assembly에 대한 내용을 런타임 차원에서 관리하고, 이를 자동으로 연결하고 있는 것입니다. 직접 프로젝트에서 참조를 하지 않았다고 할지라도 그러합니다.

 

그리고 이러한 기능 위에 DLR과 더불어서 이미 LINQ에서 소개된 적이 있는 Expression Tree 해석 엔진에 의하여 C# 기준으로 작성된 코드를 Object Binder가 가지고 있는 정보와 일치시켜 정확한 기능을 하는 실제 코드를 컴파일 과정에서 작성하게 되는 것입니다. 이것은 형식 정보를 읽어서 매번 같은 컬렉션을 여러번 반복하면서 조회하는 Reflection 기반의 프로그래밍보다 훨씬 빠르게 동작하고, 훨씬 정확도가 높습니다.

 

위의 코드를 실행한 결과는 아래와 같습니다. 중간에 어떤 메시지를 표시할 것인지를 묻는 브라우저의 프롬프트 창에 원하는 메시지를 넣어보는 것도 괜찮을 것입니다.

 

 

Dynamic Programming에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/dd264736(VS.100).aspx 의 내용을 참고하시면 도움이 될 것입니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

근래에 들어서 ASP.NET AJAX도 나왔고 본격적으로 Visual Studio 2008이나 Visual Web Developer 2008을 통해서 Java Script 인텔리센스도 사용할 수 있게 되면서 참 좋아졌습니다. 하지만 JavaScript에서도 OOP가 가능하다는 사실을 모르는 분들도 많고 알고 난 뒤의 당황스러움 또한 말로 표현하기 어려우실 겁니다. :-)

JavaScript의 OOP는 기존의 OOP 프로그래밍 언어에서 최소한의 내용만을 가져왔고 복합적인 형태를 띕니다. 아래의 연속된 박스들을 보면서 어떻게 OOP가 완성되는지 살펴보도록 하겠습니다.

function myClass()
{
    // 보통은 이곳에 함수의 내용을 프로그래밍하는 것으로 알고 있고 그렇게 합니다.
}
function myClass()
{
    // 그러나, this라는 키워드가 있습니다. 그리고 this라는 키워드에 임의의 변수를 새로 정의하는 것이 가능합니다.
    this.something = 'Hello World!';
}
function myClass()
{
    // 한걸음 더 나아가서, something의 내용을 브라우저의 메시지 박스로 띄워주는 함수도 만들어볼까요?
    this.something = 'Hello World!';
    this.showSomething = function() {
        alert(this.something);
    }
}
var test = new myClass();
test.showSomething();

위의 연속된 박스들을 보면서 몇 가지 특징을 한꺼번에 설명해보겠습니다.

우선 myClass라는 함수이자 클래스는 보통의 함수로 사용되면 의미가 없습니다. 반드시 new 연산자에 의해 생성될 필요가 있습니다. 이 때, myClass 안에 들어있는 선언부 외의 모든 일반적인 코드들은 myClass의 생성자와 같은 일을 합니다.

그리고 따로 선언한 적이 없는 변수나 함수가 this 키워드에 이름을 지정하는 것 만으로 생성이 되는 것을 알 수 있는데, 이렇게 생성된 변수나 함수 모두 액세스 한정자가 public인 멤버로 볼 수 있습니다. 만약 로컬 변수를 사용하고 싶어서 var 키워드를 써서 변수를 정의했다면 로컬 변수로도 취급됩니다. var 키워드의 경우 브라우저의 해석 방법에 따라서는 private 액세스 한정자 멤버로 취급될 수 있는것도 같습니다만 정확한 것은 아닙니다.

이와 같이 JavaScript OOP를 이용하여 새로운 형식을 만든다는 것은 어려울 것이 없는 단순명료한 작업입니다. 여기에 기존의 브라우저들이 제공해왔던 다양한 형태의 API와 XMLHttpRequest와 같은 서비스를 결합시킨다면 유용할 것입니다. ASP.NET AJAX를 비롯하여 여러 JavaScript 고급 서비스들은 JSON (Java Script Object Notation)을 통하여 직렬화와 역직렬화 서비스를 구현하고 있으며 이를 통하여 클래스에 영속성을 부여하기도 합니다.

JavaScript OOP를 성공적으로 활용하는 사례는 도처에 널려있습니다. ASP.NET AJAX의 XML 웹 서비스 연동 기능, 자바스크립트 객체 영속성을 위한 JSON, 자바스크립트 코드 검증 및 분석 도구인 JSLINT 등이 있습니다.

ASP.NET AJAX를 통하여 새로운 기능을 배우는 것도 좋지만 JavaScript의 OOP 능력도 시험해보고 좀 더 낳은 코드를 제작할 수 있도록 아이디어를 찾아보는 시도 또한 중요할듯 싶습니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

개인적인 호기심에 Java Script 기반의 암호화 알고리즘 구현이 있을까 검색해보게 되었다. 혹시가 역시였는데 매우 다양한 버전의 Java Script 기반의 암호화 알고리즘을 찾을 수 있었다. 클라이언트에서 데이터를 암호화한 후 이것을 서버로 전송하고 이것을 서버에서 같은 비밀 키를 사용하여 해독한다는 개념은 이제는 너무 일반적인 것이라 굳이 언급하지 않아도 될 정도다. 하지만 놀랍게도 이런 구현 절차를 ActiveX에 너무 많이 기대고 있다는 것 또한 사실이다.

ActiveX 없이 다중 브라우저를 지원하면서도 일정 수준 이상의 보안을 충족하는 암호화 시스템을 어쩌면 간단히 구현해볼 수도 있지 않을까라는 호기심이 생겨서 몇 번 코드를 끄적여보았을 뿐인데 개인적으로나 일반적인 커뮤니티에 적용하기에는 딱 좋은 수준의 암호화 시스템이 나와서 글을 써본다. Security Critical한 서비스에서는 HTTPS, SSL, IP/sec 등을 사용하는 것이 100배 안전하지만 이것은 어디까지나 일상적인 암호화만을 다루는 것이다.

기본적인 원리는 간단하다. 같은 Java Script Source Code를 가지고 하나는 Internet Browser용 Java Script Code로 사용하고 또 하나는 JScript .NET 컴파일러용으로 패키징하여 ASP.NET에 통합하는 것이다. 이 글에서는 AES (Advanced Encryption Standard) 알고리즘을 채택하였다.

Java Script AES Implementation: http://www.movable-type.co.uk/scripts/aes.html

위의 사이트에서 핵심적인 AES 구현을 먼저 가져왔다. AES 알고리즘과 비밀 키를 통하여 평문을 암호문으로, 암호문을 평문으로 바꾸는 것이 정확하게 작동한다는 것을 테스트하였다. 하지만 암호문을 평문으로 바꾸는 과정에 있어서 암호문이 바이트의 배열로 출력된다는 점이 걸린다. 인코딩에 따라서는 완전히 다른 내용으로 읽혀져 손상될 가능성이 있기 때문이다. 그래서 BASE64 알고리즘을 다시 찾게 되었다.

Java Script BASE64 Implementation: http://rumkin.com/tools/compression/base64.php

AES 암호문을 BASE64로 보호하고, BASE64 디코딩으로 얻어낸 AES 암호문을 평문으로 바꾸는 것 또한 정확히 동작함을 확인하였다. 그리고 이번엔 정말 실용성이 있는지 확인해보고 싶어서 2바이트 문자열을 가지고 암호화 복호화를 시험해보았다. 하지만 이번엔 정확히 복원해내지 못한다는 것을 확인할 수 있었다. 다행히 2바이트 문자열에 대해서는 자바스크립트 내장 함수인 encodeURI와 decodeURI를 통하여 처리할 수 있었다. 평문에 관한 문제는 해결이 되었지만 비밀 키의 경우에는 이 방법도 의미가 없었다. 비밀 키는 1바이트 문자열 수준에서 해결해야 하는듯 보였다.

이러쿵 저러쿵하여 만든 JavaScript 코드와 바이너리를 ZIP 파일로 묶어서 올려본다. 여러 메서드가 있지만 이 글의 내용을 반영하여 만든 실질적인 메서드는 다음과 같다.

// JavaScript
AesEncrypt128(plainText, password);
AesEncrypt192(plainText, password);
AesEncrypt256(plainText, password):
AesDecrypt128(cipherText, password);
AesDecrypt192(cipherText, password);
AesDecrypt256(cipherText, password):

// C# (Need JScript.NET Runtime Assembly)
SecurityManaged.ComplexAes aesModule = new SecurityManaged.ComplexAes();
aesModule.AesEncrypt128(plainText, password);
aesModule.AesEncrypt192(plainText, password);
aesModule.AesEncrypt256(plainText, password);
aesModule.AesDecrypt128(cipherText, password);
aesModule.AesDecrypt192(cipherText, password);
aesModule.AesDecrypt256(cipherText, password);

클라이언트 측에서는 AesEncrypt로 보호할 내용을 암호화한 후 서버에 전송하고, ASP.NET - 또는 - 이를 받아들일 소켓 서버 등에서는 SecurityManaged.dll 파일을 레퍼런스로 참조하고 SecurityManaged.ComplexAes 클래스의 인스턴스를 만들어 위의 AesDecrypt로 내용을 복구하면 되겠다. 참고로 128/192/256은 키의 길이에 해당된다.

첨부된 파일 안의 .Managed.js 파일은 JScript.NET 문법에 맞게 재배치한 것으로 DLL로 컴파일하는 것을 가능하게 해준다. 안의 내용이나 코드 문법은 오리지널 Java Script과 전혀 차이가 없지만 닷넷 어셈블리로 만들기 위해서 package 구문과 class 구문을 추가하였을 뿐이다. 또한, 가능성만을 타진해보기 위함이었으므로 JScript.NET에서만 가능한 명시적인 형식 지정 또한 누락되어있다. 만약 좀 더 최적화를 원한다면 코드를 수정해서 사용할 것을 권하며 필요한 경우 어트리뷰트 지정을 통하여 지연된 서명을 추가해볼수도 있겠다.

닷넷 프레임워크 2.0을 설치하였다면 명령 프롬프트에서 다음과 같이 입력하면 원하는 어셈블리를 직접 얻을 수 있다. (이 작업을 위해서 Visual Studio 2005나 2008은 필요하지 않다.)

%windir%\microsoft.net\framework\v2.0.50727\jsc.exe /target:library AesImpl.managed.js

이제 우리들만의 일상적이고도 간단한 AES 암호화 알고리즘 시스템을 얻을 수 있게 되었다. 그 다음 활용 방안은 다시 고민해봐야 하겠다. 자바스크립트 기반에 닷넷까지 지원되니 ASP.NET AJAX와 Silverlight에도 잘 어울릴듯 하다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

오늘은 자투리 시간을 이용하여 Visual Web Developer 2008을 설치해서 가장 써보고 싶었던 기능인 JavaScript 편집 기능을 활용해 보았다. 평소에 JavaScript 에디터 중에 무료로 사용할 수 있으면서도 완벽한 기능을 보여주는 에디터가 없는게 큰 불만이었던터라 무척 반가웠다.

Visual Web Developer 2008의 자바스크립트 기능이 특별한 이유는 바로 JavaScript OOP를 지원하기 때문이며 부수적으로 HTML DOM을 완벽하게 해석하기 때문에 정확한 코딩을 할 수 있어서 좋다. 만약 JavaScript를 분석할 일이 있지만 까탈스러운 문법때문에 고민중이라면 당장이라도 Visual Web Developer 2008만은 다운로드받아서 활용해보길 바란다. 덤으로 테스트용 웹 서버까지 따라오므로 IIS도 필요없다.

본업인 닷넷 프레임워크 기반 개발 환경에 대해서도 당연히 관심이 있기에 ASP.NET AJAX가 2005때보다 얼마나 더 개발하기 편리해졌는지, 그리고 WCF (Windows Communication Foundation) 프레임워크 기반의 서비스 개발의 능력도 체크해 볼 생각이다.

Visual Web Developer 2008은 이 글을 쓰는 현 시점에서 아직까지 영문판 전용이지만 곧 한글판도 나올 것으로 보인다. http://msdn.microsoft.com/express 에서 받을 수 있다.

아래는 기념으로 만든 예제 코드이다. 요즈음은 어떤 환경이던간에 Hello World를 못할리가 없으므로 나는 예제 코드로 좌항과 우항을 더해서 결과값을 반환하는 사칙 연산 로직을 앞으로의 새로운 프로그래밍 언어에 대한 시험 코드로 써볼 생각이다.

[CODE]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
    <script type="text/javascript">
    function exception(content) {
        this.message = content.toString();
       
        this.alert = function() {
            alert(this.message);
        }
       
        this.toString = function() {
            return this.message;
        }
    }

    function calc(leftVal, rightVal) {
        this.left = parseInt(leftVal.toString(), 10);
        this.right = parseInt(rightVal.toString(), 10);
       
        if (isNaN(this.left)) {
            throw new exception('left is NaN!');
        }
       
        if (isNaN(this.right)) {
            throw new exception('right is NaN!');
        }
       
        this.add = function() {
            return this.left + this.right;
        }
       
        this.sub = function() {
            return this.left - this.right;
        }
       
        this.multi = function() {
            return this.left * this.right;
        }
       
        this.div = function() {
            if (this.right == 0) {
                throw new exception('div/0!');
            }
            return this.left / this.right;
        }
       
        this.mod = function() {
            return this.left % this.right;
        }
       
        this.pow = function() {
            return Math.pow(this.left, this.right);
        }
    }
    </script>
</head>
<body>
    <div id="Test"></div>
    <script type="text/javascript">
    var test = new calc(3, 4);
    alert(test.add());
    alert(test.sub());
    alert(test.multi());
    alert(test.div());
    alert(test.mod());
    alert(test.pow());
    </script>
</body>
</html>


[/CODE]
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)
.NET Framework 2.0에서 구현이 잘 된 컴포넌트로 손에 꼽을 수 있는 것이 바로 WebBrowser 컨트롤이다. 이 컨트롤은 단순히 Internet Explorer를 가져온 것이 아니다. 대표적인 예로 특별한 노력을 기울이지 않아도 상호 운용이 가능하다는 점이다.

1. JScript에서 Host 프로그램에 액세스하기

JScript에서 Host 프로그램을 접근하고 사용하는 방법은 간단하다. 문서를 로드하기 전에 WebBrowser 컨트롤 객체의 속성 중 하나인 ObjectForScripting에 원하는 객체를 지정해 주면 된다. 단, 여기에 지정할 수 있는 객체는 반드시 System.Runtime.InteropServices.ComVisibleAttribute가 지정되어있어야 하고 물론 값을 True로 설정해 놓은 상태여야 한다.

로드할 문서 안의 자바스크립트에서는 window.external 객체를 통하여 Host 프로그램이 노출한 객체를 사용할 수 있다. 만약 HelloWorld라는 클래스를 노출하였고 이 클래스의 멤버 함수 ShowMessage 함수를 실행하려 한다면 window.external.ShowMessage() 와 같이 기술하면 되겠다.

2. Host 프로그램에서 JScript에 액세스하기

문서가 완전히 로드가 되었을 때를 전제로 한다. 문서가 완전히 로드된 상태에서 JScript 함수를 단독으로 실행하고 그 결과값을 되돌려 받는 방법은 간단하다. WebBrowser.Document.InvokeScript 함수를 이용하는 방법이다. InvokeScript 함수는 두 가지 버전이 있는데, 매개 변수를 받는 버전과 받지 않는 버전이다. 매개 변수는 System.Object의 배열 형태로 전달되고 결과값은 System.Object 형태로 반환된다. 반환 값이 없는 함수의 경우 null 참조 (Visual Basic의 Nothing)를 반환할 것이다.

3. 신경써야 할 것들

COM과 닷넷 사이가 완전히 자유로운 것은 아니다. 그러므로 몇 가지 챙겨야 할 것이 있다. 되도록 함수와 프로퍼티 수준에서 연동을 마무리하는 것이 좋으며 콜백 등을 구현하고자 한다면 테스트해야 할 것이 많을 것으로 생각된다. 또한 닷넷 2.0의 제네릭은 COM으로 전달이 불가능하다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)