288 Results for 'Programming/Silverlight'

  1. 2008.08.21 싸이월드, 실버라이트로 만든 테마앨범 이벤트 공개
  2. 2008.08.20 Custom Control Helper (2)
  3. 2008.08.18 실버라이트의 Reflection 제약
  4. 2008.08.12 Visual Studio 2008 SP1 과 Silverlight Tools
  5. 2008.07.20 SilverlightDefaultStyleBrowser改 for Beta 2 (1)
  6. 2008.07.17 실버라이트 2 베타2에서의 silverlight.js 활용
  7. 2008.07.17 실버라이트 2 베타2 중요업데이트 배포
  8. 2008.07.11 Error1001.com!!
  9. 2008.07.01 실버라이트 2의 이벤트 라우팅 (4)
  10. 2008.07.01 마이크로소프트와 어도비의 '나무'를 보는 관점의 차이 (6)
  11. 2008.06.29 [MSDN] 네트워크 보안 접근 제약 (1)
  12. 2008.06.28 [MSDN] URL 접근 제약
  13. 2008.06.25 SBS, 동영상 뉴스 페이지에 실버라이트 도입 (1)
  14. 2008.06.25 PIP 구현의 기초 (4)
  15. 2008.06.13 하나더 TV, 갑자기 우울해졌네요. (4)
  16. 2008.06.12 [Remix Korea 08] Nexon (2)
  17. 2008.06.12 [Remix Korea 08] Megazone
  18. 2008.06.12 [Remix Korea 08] KBS 올림픽 방송 (1)
  19. 2008.06.12 [Remix Korea 08] Innotive (3)
  20. 2008.06.12 [Remix Korea 08] iMBC의 하나더 TV (8)
  21. 2008.06.07 실버라이트 2 베타2 런칭! (3)
  22. 2008.05.29 휴즈플로우는 지금 REMIX SEA 08에! (6)
  23. 2008.05.27 [Don't Panic] URI에 존재하지 않는 참조를 사용하면 먹통이 된다?
  24. 2008.05.25 [MEMO] 겨우 50개정도의 아이템이 왜이렇게 늦게 뜨지?
  25. 2008.05.20 [TIP] XmlSerializer로 데이터 교환을 가볍고 편리하게
  26. 2008.05.19 REMIX Korea 08로 여러분을 초대합니다! (2)
  27. 2008.05.19 [TIP] 실버라이트2 설치 후 자동으로 리프레시 하기
  28. 2008.05.19 실버라이트 1.1를 공부해야 하는가? (3)
  29. 2008.05.17 [TIP] XAML에서 사용하는 색상 표현 문자열을 Brush로 반환 (1)
  30. 2008.04.10 [Don't Panic] Object reference not set to an instance of an object (3)
사용자 삽입 이미지

싸이월드에서 실버라이트로 만든 테마 앨범을 공개했어요.
테마 앨범은 지난 Remix Korea 08에서도 잠깐 소개되었죠. 단순히 Remix 이벤트로 그치지 않고 결실을 맺었네요.
바로가기 -> http://www.cyworld.com/event/promotion/2008_themeAlbum/ThemeAlbumEvent.asp

...그런데...

전 싸이월드 아이디가 없다는거... -_-;;
자세한 소개는 길버트님의 글을 참고하세요;;
http://gilverlight.net/2924

박스마일님 그동안 수고 많으셨어요^^
Posted by gongdo

Submit comment.

실버라이트 2 베타 2에서 가장 중요한 업데이트는 바로 Visual State Manager(이하 VSM)의 지원이었죠. VSM은 실버라이트가 강조하는 개발자와 디자이너의 분리된 협업을 더욱 잘 지원하게 해주고 개발 생산성을 정말 엄청나게 향상시켰죠. 저 역시 베타 1때의 커스텀 컨트롤 만들었던 것과 지금을 비교하면 그저 눈물이 나올 뿐이에요.

그렇지만 아직 커스텀 컨트롤도 해결해야 할 문제가 몇 가지 있는데요, 그 중에서 실제 개발 할 때 가장 귀찮고 시간이 많이 걸리는 부분은 바로 코드에서 정의된 템플릿 파트나 Visual State Group 및 Visual State의 이름을 가지고 generic.xaml에 기본 템플릿을 정의해야 한다는 점이에요. 개발자와 디자이너가 '이름'이라는 수단으로 일종의 계약을 맺는거죠. 일단 개념 상으로는 굉장히 좋아요. 먼저 컨트롤이라는 부품의 역할과 필요한 요소를 먼저 정의한 후 그 정의에 부합하는 한에서 디자인을 마음대로 할 수 있으니까요.

그러나, 개발자의 입장에서 '이름' 즉, 문자열에 기반한 계약 관계란 귀찮고 불안하기 짝이 없는 물건이에요. 만약 프로젝트를 진행하다가 모종의 이유로 인해 이 이름을 바꿔야할 필요가 있다면? 특정 이름이 더 이상 사용되지 않는다거나 새로 추가 되었다면? 게다가 이런 일은 상당히 자주 발생하죠. 이런 상황에서는 대체로 개발자 해당 '문자열'을 수작업으로 검색해서 바꿔주는게 일반적이에요. 문제는 이것이 실수를 만들기 매우 쉬운 프로세스라는 것이에요. 코드만으로 구성된 프로그램에서는 이런 일이 발생하지 않죠. 왜냐면 만약 코드에서 어떤 변수의 이름을 바꾸거나 삭제했다면 컴파일러가 곧바로 그 사실을 알려주고 에러 메시지를 뿜어내니까요. 하지만 단순한 문자열은 그 내용을 바꿨는지 어쨌는지 아니 심지어 그 문자열이 무슨 뜻인지 조차 컴파일러는 알지 못하니까요.

이 문제는 과거 실버라이트 1.1의 사용자 컨트롤에서도 있었던 문제였어요. 요컨대 XAML에서 x:Name 어트리뷰트로 선언한 이름을 코드 비하인드에서 일일이 수작업으로 그 엘리먼트의 참조를 만들어야만 했었죠.

이 문제는 실버라이트 2 베타 1이 나오면서 해결되었어요. 바로 사용자 컨트롤을 생성하면 XAML 마크업과 코드 비하인드가 쌍으로 만들어지고 XAML에서 x:Name 어트리뷰트로 선언된 이름은 Xaml precompiler에 의해 자동으로 동일한 이름을 갖는 멤버 변수로 선언이 되죠.

[UserControl이란 사용자 컨트롤을 만들면 위와 같이 XAML 마크업과 코드 비하인드 외에 컴파일러가 자동으로 만들어주는 g.cs파일이 생성됩니다.]

이렇게 되어 사용자 컨트롤을 만들 때의 귀찮은 단순 노가다가 사라졌을 뿐만 아니라 디자이너가 자유롭게 XAML상의 x:Name어트리뷰트를 바꿔도 개발자는 그 사실을 빠르게 캐치 할 수 있게 되었죠.

불행하게도, 아직 커스텀 컨트롤에는 이러한 매커니즘이 적용되어 있지 않아요. 디자이너는 단지 generic.xaml에 컨트롤의 스타일을 XAML로 정의할 뿐이고 개발자는 단지 코드 비하인드에서 필요한 요소들을 수작업으로 참조하게 되죠. 마치 1.1에서 했던 그것처럼요!

휴... 사설이 길었죠? 네 바로 이런 이유로 Custom Control Helper를 만들어봤어요.

이 툴을 만들면서 굉장히 삽질을 많이 했는데요, generic.xaml과 커스텀 컨트롤의 DefaultStyle 적용 매커니즘은 굉장히 복잡하기 때문이죠. 그 옛날 사용자 컨트롤처럼 단순히 XAML 코드에서 x:Name으로 선언된 어트리뷰트를 가진 모든 엘리먼트를 멤버 변수로 1:1 매칭하기만 하는 코드와는 차원이 달랐어요.

먼저 일반적인 Custom Control을 만들 때 가장 필수적인 요소들을 뽑아 보죠.

  • Custom Control은 DefaultStyle로 자기 자신의 Type을 사용합니다. 즉, generic.xaml에 선언된 Style중 TargetType이 자기 자신의 Type과 일치하는 스타일을 선택합니다.
  • Custom Control에 포함될 VisualStateGroup과 VisualState의 이름을 internal 멤버로 선언합니다. 이 때 Custom Control이 이미 부모 Custom Control로부터 상속받았을 가능성도 있으므로 부모 Custom Control이 해당 멤버를 이미 가지고 있을 경우는 제외합니다.
  • Custom Control에 포함될 Template Part를 리스트업 합니다. 일반적으로 Template Part의 대상으로는 Custom Control의 RootElement의 Resources에 포함된 Storyboard, 그리고 RootElement를 포함한 모든 하위 엘리먼트 중에서 x:Name 어트리뷰트를 선언한 엘리먼트를 의미하며 그 하위 엘리먼트들은 자기 자신의 Style 정의를 따로 갖을 수도 있으므로 이런 부분은 제외합니다. 마찬가지로 Template Part는 부모 Custom Control로부터 상속이 가능하므로 이미 선언 되었다면 제외합니다.
  • Custom Control을 위한 partial class 문자열을 생성합니다. 이 때 해당 클래스에 포함된 모든 Template Part들의 Type을 사용할 수 있도록 적절히 using 문도 넣어줘야 합니다.
  • Custom Control의 partial class는 InintializeTemplate이라는 멤버 메서드를 정의하고 그 메서드 내에서 스타일이 정의하고 있는 Tempalte Part들을 멤버 변수로 참조합니다. 이 때 해당 Template Part가 null이 아닌데 Type이 일치하지 않는 경우는 Assertion을 발생시키는 코드도 넣습니다.
  • Template Part 참조시의 Assertion 코드는 단순히 똑같은 코드를 반복할 수도 있고 클래스의 멤버 메서드로 묶어서 쓸 수도 있고 혹은 해당 클래스의 부모 클래스에서 이미 상속했을 수도 있습니다.
  • 컨트롤의 템플릿을 정의하는 XAML은 단순히 이름만 정의했을 뿐 실제로 코드에서 굳이 참조하여 사용할 필요가 없는 경우가 더 많습니다. 따라서 이름을 가지고 있는 엘리먼트 중에서 Template Part로 등록할 엘리먼트를 선택할 수 있어야 합니다.

...만들다 보니 진짜 복잡하네요...
여튼 이런 조건을 만족시키기 위해서는 XAML 만 분석해서는 답이 안나와요. 그래서 차선으로 선택한 것은 아예 컴파일 되어 있는 XAP 패키지를 직접 다운로드하고 그 안에 들어있는 어셈블리들을 동적으로 로드한 후 정확한 Type 분석 및 상속 관계를 파악하여 작업해야 했어요.

완벽한 형태가 되려면 Visual Studio 플러그 인으로 개발하면 더 좋겠지만 더 이상은 귀찮아서 손대기가 싫어요 -_-;

사용법은 간단하게 [Browse]를 클릭하여 XAP파일을 선택하세요. 주소창에 http://...처럼 웹에서 직접 선택하는 것도 가능해요.

선택된 XAP 파일내에 어셈블리들을 로드하고 각 어셈블리에 generic.xaml이 있을 경우만 리스트업하죠.

분석할 어셈블리를 선택하면 generic.xaml에서 스타일이 정의되어 있는 커스텀 컨트롤의 목록이 나오고 Options에서 Template Part를 참조하는 방법을 선택할 수 있으며 Required template parts에서 Template Part로 등록할 엘리먼트의 이름을 체크하면 돼요.

왼쪽 아래의 TextBox는 원본 generic.xaml 코드이고 오른쪽 TextBox는 현재 선택된 커스텀 컨트롤에 대한 partial class 코드에요. 이 코드를 복사해서 프로젝트에 새 파일로 추가하고 해당 클래스의 선언을 partial 로 변경해준 후 OnApplyTemplate 오버라이드 구현에서 InitializeTemplate()을 호출하면 돼요.

사실 이 샘플은 그냥 제가 쓸려고 만든거라 아마 별 도움은 안되겠지만, 혹시 XAP 파일에서 어셈블리를 얻어와서 분석하는데 관심이 있다면 소스코드가 도움이 될 거에요.


없을 걸 알지만 피드백 기대합니다. :)

Posted by gongdo

Submit comment.

  1. Favicon of http://blog.powerumc.kr BlogIcon 땡초 2008.08.20 14:35  comment URL  Edit/Remove  Submit comment.

    VSX DTE Object 의 CodeModel 이 딱 떠오르네요
    아마 보시면 참고가 될 것 같네요..

후우... MSDN의 중요함을 다시 한번.
실버라이트에서도 System.Reflection을 통해 닷넷의 강력한 리플렉션 코드를 사용할 수 있는데요, 하지만 부분적으로만 신뢰된Partial trusted 애플리케이션의 특성을 고려했는지 몇 가지 제약을 걸어뒀네요.

가장 강력한 제약은 private 접근자에 대한 Reflection이 불가능하다는 점인데요, 테스트 해보니 protected도 마찬가지에요. MSDN에서도 public 접근자가 붙은 멤버에 대해서만 접근이 가능하다는군요. 마찬가지로 internal 접근자의 경우 같은 프로젝트 내에서는 접근이 되겠지만 외부 어셈블리일 경우는 불가능하겠죠.

참조
http://msdn.microsoft.com/en-us/library/stfy7tfc(VS.95).aspx
Posted by gongdo

Submit comment.

네 오늘 한꺼번에 나왔네요.

만약 Silverlight 2 Tools Beta 2 for Visual Studio 2008가 설치되어 있다면 먼저 http://www.microsoft.com/downloads/details.aspx?FamilyId=A494B0E0-EB07-4FF1-A21C-A4663E456D9D&displaylang=en에서 언인스톨러(?)를 사용해서 환경을 클리어 하고요,

VS2008 SP1 다운로드는 http://www.microsoft.com/downloads/details.aspx?FamilyID=27673c47-b3b5-4c67-bd99-84e525b5ce61&DisplayLang=en

Silverlight 2 Beta 2 Tools for SP1은 http://www.microsoft.com/downloads/details.aspx?FamilyId=50A9EC01-267B-4521-B7D7-C0DBA8866434&displaylang=en 여기에서 다운 받으세요.

뭐 당연하게도 한글판은 아직 지원하지 않으니까 영문판 Visual Studio에서만 가능하고요. 또 혹시라도 Silverlight를 위한 ADO.NET DataService 툴을 사용 중이라면 아직 더 기다려야 할거에요.


설치는 딱히 문제가 없었고요, 설치가 완료되면 위와 같은 정보를 확인할 수 있죠.
Posted by gongdo

Submit comment.

boxmile 님과 이과장님이 알려주신 유용한 유틸리티, SilverlightDefaultStyleBrowser.
이게 없으면 실버라이트 스타일을 어떻게 했을까 몰라요.^^
무지 유용한 툴이니까 한번쯤 꼭 써보세요.



여튼 한가지 불편한 점은 스타일의 일부만 선택하고 Ctrl+C를 눌렀을 때 테스트 복사가 되지 않는다는 점이었는 데요, Ctrl+C로 클립보드에 복사되도록 코드를 수정해서 올립니다.
보너스로 각 엘리먼트 앞에 있는 접기/열기 표시인 -, +도 제거하도록 했어요.

Posted by gongdo

Submit comment.

  1. 건태 2008.07.20 17:49  comment URL  Edit/Remove  Submit comment.

    beta2 Control dll 도 기본으로 추가 시켜주세요..^^

실버라이트 2에 들어와서는 간편한 <object>태그 만으로 실버라이트 플러그인을 초기화할 수 있기 때문에 더 이상 silverlight.js를 사용하지 않아도 되게 되었죠.

그러나 몇몇 시나리오에서 여전히 silverlight.js를 사용하여 초기화 할 필요가 있는데요,

  • 특정 버전의 실버라이트를 설치할 수 있는 브라우저인지 여부 검사
  • 특정 버전의 실버라이트가 설치되어 있는지 여부 검사
  • 실버라이트 설치가 완료되었을 때 곧바로 애플리케이션을 초기화

이런 상황을 위해 silverlight.js에 다양한 메서드와 프로퍼티가 준비되어 있죠.

현재 silverlight.js는 새로운 브라우저나 OS에 대한 빠른 대응을 위해 별도로 관리되고 있어요. 특이한 점은 기존의 기능 중 실버라이트를 지원하는 브라우저인지 여부를 체크하는데 사용했던 Silverlight.supportedUserAgent() 메서드가 더 이상 silverlight.js에 포함되지 않고 silverlight.supportedUserAgent.js라는 별도의 파일로 관리된다는 점이죠. 이 두 파일의 최신 버전은 각각 다음의 링크에서 다운로드 받을 수 있어요.

더 자세한 내용은 What's new in the Silverlight 2 Beta 2 SDK's Silverlight.js file? 에서 실버라이트 2 베타 2 SDK에 적용된 silverlight.js 파일에 대한 내용을 살펴볼 수 있어요. 저도 몰랐던 다양하고 유용한 기능들이 추가되었더군요.

silverlight.js 활용하여 다음과 같은 시나리오의 초기화를 수행하는 간단한 프로젝트를 첨부했으니 참고하세요.

  • 실버라이트를 설치 할 수 있는지 여부 검사
  • 실버라이트가 설치 되었는지 여부 검사
  • 실버라이트가 설치 되지 않았을 경우 커스터마이징한 HTML UI 표시
  • 실버라이트 설치가 완료된 경우 애플리케이션을 자동으로 초기화(단, IE 전용)

다운로드 :


※추가 :
혹시 이번 업데이트 이후에 비주얼 스튜디오에서 디버깅이 되지 않는다거나 하면 Silverlight Tools Beta 2 for Visual Studio 2008을 다시 설치해 보세요.
제 경우는 특별히 기존 버전의 Tools를 제거하지 않았어도 문제가 없었는데, 혹시 문제가 있다면 KB949325를 제거하라는 군요.

또한 저는 어디까지나 영문 버전만을 사용하기 때문에 한글판 Visual Studio나 Tools에 대해서는 어떻게 작동될지 알지 못한다는 점도 참고해 주세요.
Posted by gongdo

Submit comment.

16일자로 실버라이트 2 베타2를 위한 중요 업데이트가 윈도우 업데이트에 뜨네요.
특별히 달라진건 없고 다만 파이어폭스3에 대한 지원 향상이 가장 큰 원인 인듯.
기존의 애플리케이션에도 전혀 영향이 없으니 뭐 한번 깔아보세요 :)

자세한 내용은...
http://support.microsoft.com/kb/955011
Posted by gongdo

Submit comment.

실버라이트 개발 중 겪는 숱한 에러 메시지와 익셉션들 그리고 공포의 화이트 스크린(!!)...
이런 문제들을 정리하기 위해 Error1001.com이 개장했어요.
실은 개장한지 한참 되긴 했는데 공지만 덜렁 있으면 너무 썰렁하잖아요? ^^;

Error1001은 실버라이트 1.0과 1.1 시절에 개발자들을 패닉에 빠지게 하는 불친절한 에러메시지에서 따온 이름이에요. 아마 그시절 실버라이트 개발자라면 Error code 1001의 분노를 아직 기억하실거에요.


실버라이트 개발자들의 분노를 샀던 바로 이 메시지 박스(크아아아아아!!)

실버라이트는 아직 역동적으로 발전하고 있는 플랫폼이기 때문에 다소 거슬리는 버그나 오류도 많이 가지고 있죠. Error1001에서 서로의 경험을 공유할 수 있으면 좋겠어요. Error1001은 팀블로그로 운영되고 필자가 되고 싶은 분은 언제든지 Error1001의 공지에 비밀 댓글을 남겨주세요. :)
Posted by gongdo

Submit comment.

※역시 똑같은 내용도 MSDN을 그대로 번역하면 당췌 댓글이 안달리고 별 도움도 안되는 것 같아요. 앞으로는 가급적이면 MSDN에 99% 있는 내용이더라도 나름의 분석과 생략압축으로 좀 더 읽기 쉽게 써야겠네요. 그래도 중요한 건 대부분 MSDN에 다 있으니 제대로 공부하시는 분이라면 꼭 참조에 있는 링크들을 찾아보시길.


실버라이트 2는 보다 정교하고 합리적인 이벤트 모델을 채택하고 있죠. 이 이벤트 모델은 WPF의 그것과 매우 유사하지만 축소된 부분이 많이 있어요. 이 글에서는 실버라이트 2에서의 이벤트 모델, 특히 라우팅과 관련된 이벤트 모델에 대해 알아보도록 할게요.

실버라이트 이벤트 모델

실버라이트는 개념적으로 크게 입력 이벤트input event와 비입력 이벤트non-input event라는 두 종류의 이벤트로 구분하고 있어요. 간단하게 차이점을 살펴보면 입력 이벤트는 마우스 클릭, 키보드 입력과 같이 사용자와의 상호 작용 의해 발생하는 이벤트를 말하고 비입력 이벤트는 다운로드 완료, 타이머의 Tick과 같이 애플리케이션 코드의 흐름에 따라 발생하는 이벤트를 말하죠.

입력 이벤트

실버라이트는 플러그인 아키텍처로 브라우저 위에 호스팅되죠. 이 점은 제가 누누히 강조하는 부분인데요, 실버라이트는 웹 브라우저 위에 호스팅되는 클라이언트 기술이라는 거죠. 여튼, 입력 이벤트는 브라우저에 의해 처리된 것이 실버라이트 플러그인으로 전달되고 실버라이트 플러그인은 거기에 대한 이벤트를 만들게 된다는 점을 기억하세요.

비입력 이벤트

비입력 이벤트는 일반적으로 개별 오브젝트들의 상태가 변경되었음을 알리는데 사용되는데요, 특히 WebClient등의 네트워크나 BackgroundWorker와 같은 스레드관련 처럼 비동기적으로 수행되어야 하는 처리에 매우 유용하고 적합하죠.

또 MediaElement와 같이 내부적인 상태 변화가 사용자나 코드의 간섭 없이 발생하는 경우에는 이벤트 없이 처리를 한다는 건 어려울거에요.

이 외에 FrameworkElement.Loaded 이벤트 처럼 오브젝트의 라이프타임 관리에 필수적인 것도 있죠.

마지막으로 실버라이트 플러그인에서만 처리할 수 있는 비입력 이벤트가 하나 있는데요, 바로 OnError 이벤트죠. OnError 이벤트는 HTML-DOM에서의 스크립트 실행을 하는 중 발생되는 에러를 핸들링하기 위한 이벤트로 플러그인 레벨에서 동작하므로 매니지드 프로그래밍 모델까지 전달되지 않고 오직 자바스크립트 코드로만 처리가 가능해요.

이벤트 라우팅

실버라이트의 엘리먼트-여기에서는 UI를 표시하는 오브젝트-들은 서로의 포함 관계에 따라 '위', '아래'의 개념이 생기고 다른 모든 엘리먼트를 포함하는 엘리먼트를 가장 위에 놓고 그 최상위 엘리먼트에 포함되는 하위 엘리먼트들의 순서대로 트리 형태로 표현할 수 있죠. 이것을 실버라이트 오브젝트 모델(SOM)이라고 부르기도 해요.

※이처럼 오브젝트 간의 포함 관계는 전통적으로 '트리'라고 불리우고 최상위 오브젝트를 나무의 뿌리라고 하여 Root라고 부르고 각 하위 클래스들을 노드Node 그리고 각 노드의 가장 끝에 있는 클래스들을 잎사귀Leaf라고 부르죠. 그런데 이 개념은 실제 사물로 그대로 그려놓고 봤을 때는 상하 관계의 혼동을 일으키기 쉬운 것 같아요. 오브젝트 트리의 '상위'에 있는 루트 오브젝트는 실제 나무에서는 가장 아래에 있으니까요. http://gongdosoft.com/295 여기에 관련된 내용을 포스팅 했으니 참고하세요.

어쨌든 나무보다 뭔가 적절하게 비교할 수 있는 게 있으면 좋겠는데요... 혹시 좋은 생각 있으면 제보해주세요^^

트리 형태로 구성된 엘리먼트에서 어떤 이벤트가 발생했을 때 어떤 엘리먼트가 이 이벤트를 처리해야 하는가에 대한 문제가 생기죠. 버튼을 예로 들어보죠, 사용자가 버튼을 눌렀을 때 버튼을 구성하는 어떤 엘리먼트가 이벤트를 받아야 할까요? 보통은 버튼을 구성하는 다른 모든 엘리먼트를 포함하는 최상위 엘리먼트가 이것을 수행해야겠죠. 그러나 실버라이트의 버튼은 단순히 텍스트나 이미지만으로 구성되어 있지 않고 버튼 안에도 마우스의 이벤트를 처리할 수 있는 다른 엘리먼트가 포함될 수도 있어요. 이 때 마우스의 이벤트를 받는 것은 아마도 버튼 안에서 -사용자 쪽으로- 가장 앞에 있고 활성화되어 있으며 눈에 보이는 엘리먼트가 되겠죠. 만약 여기에서 이벤트의 처리가 완료된다면 이 버튼은 정상적인 버튼이라고 말할 수 없을거에요. 버튼내부에 있는 어떤 오브젝트가 마우스를 누르는 이벤트에 관심이 있다면 그 오브젝트와 버튼 자체 양쪽 모두 이벤트를 처리해야 정상적이라고 할 수 있어요.

바로 이런 경우 즉, 어떤 엘리먼트들이 트리 관계를 이룰 때 발생된 이벤트는 트리를 구성하는 부모 또는 자식에게 전달될 필요가 있고 트리를 따라서 이벤트가 전달되는 과정을 이벤트 라우팅이라고하고 이렇게 트리를 따라 마치 사실chain과 같이 전달된 이벤트를 Routed Event라고 해요.

특히 입력 이벤트는 거의 대부분 이벤트를 라우팅 할 필요가 있고 FrameworkElement.Loaded나 MediaElement의 몇몇 이벤트들 처럼 일부 비입력 이벤트도 엘리먼트 트리로 라우팅할 필요가 있죠.

엘리먼트 트리에서 이벤트를 전달하는 방법에는 발생된 이벤트를 이벤트가 발생된 엘리먼트부터 최상위 엘리먼트까지 위쪽 방향으로 올려주는 버블링Bubbling과 발생된 이벤트를 이벤트가 발생된 엘리먼트를 포함하는 최상위 엘리먼트에서 이벤트가 발생된 엘리먼트까지 아래 방향으로 내려주는 터널링Tunneling이 있어요.

위의 그림은 엘리먼트 트리와 각 엘리먼트간의 이벤트 라우팅을 잘 나타내고 있어요. WPF의 경우는 이 두 가지 경우를 다 지원하지만 불행히도 실버라이트는 이 중 버블링만을 지원하고 있으니 컨트롤을 설계할 때에 충분히 주의를 해야 해요.

이벤트 라우팅의 조건

여러 개의 엘리먼트가 트리를 이룰 때 이벤트 버블링 모델에서는 트리의 가장 아래쪽 즉, 화면상의 가장 앞쪽에 있는 엘리먼트에서 이벤트가 시작되어 그 엘리먼트를 포함하는 최상위 엘리먼트까지 전달되는데, 이 때 어떤 엘리먼트가 이벤트 라우팅 체인에 속해있더라도 다음의 조건을 만족하지 못하면 그 엘리먼트로는 이벤트가 전달되지 않아요.

  • 보일 것(Visibility = Visibility.Visible)
  • Brush로 표시되는 엘리먼트 또는 영역일 경우 Brush가 null이 아닐 것(Brush != null)
  • 활성화 속성이 있다면 활성화 되어 있을 것(IsEnabled = true)
  • 마우스 이벤트일 경우 IsHitTestVisibile이 활성화 되어 있을 것(IsHitTestVisible = true)

위의 조건에 따라 심지어 완전히 투명(Opacity=0)하여 보이지 않더라도 해당 엘리먼트는 이벤트 라우팅 체인에 속하게 되어 해당 이벤트를 받을 수 있죠. 이 점은 디자인 적으로는 아무런 역할을 하지 않지만 특정 영역에 대한 이벤트를 받고 싶을 때 -예를 들어, 미디어 플레이어의 특정 영역에 마우스 커서가 들어왔을 때 배너 광고를 보여주거나 하는 경우- 자주 활용되기도 해요.

이벤트 라우팅 경로와 원본에 대한 참조

실버라이트는 앞에서 설명한 버블타입의 이벤트 라우팅 컨셉을 지원하고 주로 다음과 같은 프레임워크 레벨의 입력 이벤트들에 사용되고 있죠.

KeyDown, KeyUp, MouseEnter, MosueLeftButtonDown, MouseLeftButtonUp, MouseMove, BindingValidationError...

일반적인 이벤트 핸들러는 이벤트를 전달해준 sender라고 하는 object 타입의 파라미터와 해당 이벤트에서 전달하고자 하는 데이터를 의미하는 e라고 하는 EventArgs(혹은 사용자 정의) 타입의 파라미터를 갖는 딜리게이트로 이루어져 있어요. 보통의 이벤트는 이벤트를 제공하는 오브젝트 즉, 발행자Publisher와 이벤트에 관심이 있는 오브젝트 즉, 구독자Subscriber로 구성되어 발행자는 sender를 자기 자신으로 설정하여 누가 이벤트를 발행했는지를 구독자에게 알려주게 되죠.

그런데 라우팅되는 이벤트의 경우 이벤트 버블의 규칙에 따라 어떤 엘리먼트에서 위와 같은 이벤트가 발생했을 때 이벤트는 엘리먼트 트리의 가장 바닥 즉, 화면상에 가장 앞에 있는 엘리먼트부터 이벤트가 전달되는데요, 이때 구독자의 입장에서 sender가 자신의 바로 앞에서 이벤트를 전달Route해 준 오브젝트인지 최초로 이벤트를 발생시킨 발행자인지를 구분할 필요가 있을 거에요.

실버라이트에서는 이렇게 라우팅된 이벤트를 전달할 때에는 이벤트 핸들러의 두 번째 파라미터로써 RoutedEventArgs또는 이것을 상속받는 특별한 데이터 클래스를 사용하여 이벤트를 발생시킨 발행자 정보를 전달하게 되죠. 예를 들어 우리가 가장 흔히 사용하는 MouseLeftButtonDown 이벤트의 정의를 보면...

public event MouseButtonEventHandler MouseLeftButtonDown

이고, MouseButtonEventHandler는 다음과 같은 딜리게이트로 이루어져 있어요.

public delegate void MouseButtonEventHandler(object sender, MouseButtonEventArgs e);

또 이 딜리게이트의 두 번째 파라미터의 타입인 MouseButtonEventArgs는 MouseEventArgs 클래스에서 파생되었고 다시 MouseEventArgs 클래스는 바로 RoutedEventArgs 클래스로부터 파생되었죠.

RoutedEventArgs는 다음과 같이 엄청나게 단순하게 구성되어 있어요.

public class RoutedEventArgs : EventArgs
{
    public RoutedEventArgs();
    public object Source { get; set; }
}

여기에서 Source가 바로 최초로 이벤트를 발생시킨 발행자에 대한 참조를 의미하죠.

정리하자면, 라우팅된 이벤트의 이벤트 핸들러에서 sender는 이 이벤트를 전달해준 엘리먼트 즉, 현재 이벤트 핸들링 체인의 직전에 있는 엘리먼트에 대한 참조를 말하고 최초의 이벤트 발행자에 대한 참조는 이벤트 핸들러의 두 번째 파라미터인 RoutedEventArgs.Source를 통해 참조하게 되요.

우리가 앞으로 클래스들과 이벤트 핸들러 및 이벤트 라우팅 체인을 만든다면 위와 같은 방식으로 만들어야 협업할 때 문제가 생기지 않을 거에요. 예를 들어 라우팅 이벤트 핸들러의 sender가 난데 없이 원본을 참조하고 있다거나 RoutedEventArgs.Source가 변경된 값에 대한 참조를 하고 있다거나 하면 안되겠죠.

근본적으로 이런 문제는 sender와 RoutedEventArgs가 object타입라서 어떤 종류의 참조라도 받을 수 있게 되어 있기 때문에 발생하는데요, 이에 대한 내용은 다음 글로 넘길께요.

어떤 종류의 피드백도 환영합니다. ^^


참조

Events Overview(Silverlight 2)
찰스 페졸드의 WPF(APPLICATION = CODE+ MARKUP) ; Chapter 9. 입력 이벤트의 라우팅
Routed Event Overview(WPF)

Posted by gongdo

Submit comment.

  1. 2008.07.03 23:44  comment URL  Edit/Remove  Submit comment.

    비밀댓글입니다

  2. dayg 2009.02.17 16:53  comment URL  Edit/Remove  Submit comment.

    이벤트 라우팅을 이해하는데 많은 도움이 되었습니다~ 좋은글 잘 보고 갑니다^^

  3. illef 2009.04.16 18:21  comment URL  Edit/Remove  Submit comment.

    여기서 설명해주신 부분은 WPF의 RoutedEvent인것 같은데요..

    Silverlight 2.0에서는 Event Routing을 지원하고 있지 않는것 같습니다. 다만 Hanler의 형태가

    RoutedEventHandler인데 이는 WPF와의 호환(Copy & Paste했을 때)을 위한 것으로 보입니다.

    제목만 WPF의 RoutedEvent로 바꾸면 될 것 같은데 혹시 제가 잘못 알고 있는게 아닌가 궁금하네요.

    혹시 댓글 보시면 확인 좀 부탁드릴께요

    좋은 내용 감사합니다.

    • Favicon of http://gongdosoft.com BlogIcon gongdo 2009.04.19 20:46  comment URL  Modify/Remove

      네, 맞아요. 실버라이트는 아직 이벤트 라우팅이나 Tunneling을 완벽하게 지원하는게 아니고 몇몇 입력 관련 이벤트가 Routing을 지원할 뿐이죠.

      다만 RoutedEvent의 경우는 필요한 경우 사용자가 직접 구현할 수 있는 부분이 있고요.

오늘 실버라이트의 이벤트 모델에 대한 고찰(이라고 쓰고 졸기라고 읽는)을 하다 보니 문득 오브젝트들의 트리 관계에 대한 표시 방식이 양사의 관점의 차이를 나타내고 있다는 생각이 들더군요. 어쩌면 이 관점은 개발자와 디자이너의 관점의 차이라고 말 할 수도 있겠죠.

마이크로소프트(개발자)는 나무(오브젝트 트리)를 볼 때 아래에서 위로, 이 나무가 어디에서 시작했는지, 어떤 구조로 이루어졌는지를 더 중요하게 여기고 이 나무의 뿌리(루트 오브젝트)에서 자라나는 가지들을 차례로 보죠. 즉, 다음과 같은 순서로 본다고 할 수 있어요.

어도비(디자이너)는 나무를 볼 때 위에서 아래로, 이 나무가 어떤 생김새를 가졌는지에 더 흥미가 있고 이 나무의 형태를 결정하는 잎사귀(Leaf)며 가지(Branch)를 먼저보게 되죠. 즉,

이런 관점이랄까요?

물론 이런 억지스런 비유로 단순화 할 수는 없겠지만, 제가 하고 싶은 얘기는 똑같은 나무를 보는데에도 이 둘은 거의 반대에 가까운 관점을 가지고 있고 그렇기 때문에 툴이나 어떤 개념에 대한 접근 방식이 차이가 난다는 거죠.

전에 UXFactory의 리건님이 포스팅한 마이크로소프트와 어도비에 관한 멋진 비유로 생각해보자면 지하 동굴에서 바라보는 나무와 고층 빌딩 꼭대기에서 바라보는 나무는 다르게 보일 수밖에 없잖아요? ^^

분명한 것은 이 둘이 보고 있는 것은 같은 나무이지만 아마도 이 둘은 이 나무를 다른 방법으로 활용하고 싶어할거에요. 마이크로소프트와 어도비는 이런 점에서 경쟁을 하겠지만, 개발자와 디자이너라면 이런 관점 차이를 서로 이해해야만 협업이 가능할거에요. :D

Posted by gongdo

Submit comment.

  1. Favicon of http://gilverlight.net BlogIcon 길버트 2008.07.01 14:57  comment URL  Edit/Remove  Submit comment.

    "지하 동굴에서 바라보는 나무와
    고층 빌딩 꼭대기에서 바라보는 나무는 다르게 보일 수밖에 없잖아요? ^^"

    '난 비유 반댈세!'
    장난이구요! 저는 황리건 과장님하고 조금 생각이 다릅니다.

    MS의 트리와 Adobe의 트리의 차이점은 아래로 쌓아나가는가, 위로 쌓아나가는가일 뿐이지,
    본질적으로 그 약속에 따라 보여주려고 하는 모습에는 큰 차이가 없잖아요.

    MS의 객체 트리는 자료구조에 충실하게 표현했다고 생각하구요. (MS가 그동안 하던대로)
    폴더 트리처럼 나중에 생긴 객체가 기본으로는 아래에 달리는 거죠.

    반면, Adobe의 레이어 트리는 현실을 충실하게 표현했다고 생각해요.
    현실에서는 아래쪽에 있는 종이를 위에 있는 종이가 덮는 게 (개발자에게 조차도) 친근하죠.

    공도씨의 맺음말에 공감합니다.

    • Favicon of http://gongdosoft.com BlogIcon 공도 2008.07.01 16:34  comment URL  Modify/Remove

      네 오브젝트의 관점에서는 그렇지만 진짜 나무는 위로 자라잖아요. 그래서 오브젝트 트리의 뿌리가 '상위'라고 표현되는게 개념상 헤깔릴 여지가 있는 것 같아요.

  2. Favicon of http://www.uxfactory.com BlogIcon dykin 2008.07.03 14:29  comment URL  Edit/Remove  Submit comment.

    제 생각에 MS와 Adobe의 관점의 차이라고 하기보다는 개발자와 디자이너의 관점의 차이가 맞는 것 같네요. 항상 개발자와 디자이너의 간격이 좁혀지지 않는 이유 중에 하나가 그 것이거든요. 디자이너는 그림을 그릴 때를 봐도 전체 스케치를 통해서 점점 세부 내용을 구체화 시켜 가는 한편, 개발자는 코드 하나, 부품 하나를 서로 엮어서 전체를 완성해 나가는 것처럼 말이죠.

    • Favicon of http://gongdosoft.com BlogIcon 공도 2008.07.03 17:02  comment URL  Modify/Remove

      네.. 사실 처음에는 아래에 있는 사진을 먼저 붙여놓고 제목걸고 글 쓰다가... 다 써놓고 보니 그렇게 되었네요;
      결론은 다크나이트 빨리 보고 싶다는거 :D

  3. Favicon of http://blog.naver.com/clazzico BlogIcon oblidust 2008.07.05 05:34  comment URL  Edit/Remove  Submit comment.

    제가 찾던 좋은내용입니다. 담아가겠습니다^^

  4. 네오군 2009.09.21 03:55  comment URL  Edit/Remove  Submit comment.

    나무의 개념보다는 아버지와 자식관계가 더 개념상 적합하지 않을까요??

    실제로 parent child 개념도 있잖아요..

    여러개의 오브젝트가 있을때.. 관계도를 그려보면 실제로 그 뿌리는 증조할아버지에서 시작해

    할아버지 - 큰 아버지 - 작은 아버지, 또 그 아버지의 자식들의 자식들.. 이런식으로 개념도를

    그려보면 하나의 엘리먼트가 가지고 있는 다른 엘리먼트들이 자기 자식들 같은 느낌이 듭니다.

    그런데.. 다시 생각해보니까... 아버지가 죽는다고 해서 아들이나 또는 그 아들의 자식이 따라 죽진 않겠군요...;; 낳기는 했으나 죽을때도 같이 따라죽진 않으니.. 트리개념과 비교하기엔 무리가 있네여..;;;

※ 이 문서는 MSDN의 Network Security Access Restrictions in Silverlight 2를 번역한 것으로 실버라이트 2 베타 2를 기준으로 합니다. 추후 정책이 변경될 경우 새로 포스팅하겠지만 기본적으로는 위의 문서를 참고하세요.

※ 번역 실력이 일천하여 흐름에 크게 중요하지 않은 부분은 생략을 했습니다.

실버라이트 버전 2 런타임은 원격 호스트에 접속하는 네트워킹 애플리케이션을 위한 두 개의 중요한 수단을 지원합니다.

  • System.Net 네임스페이스에 있는 WebClient와 Http 클래스들 - 이 클래스들은 네트워크 통신을 위해 HTTP 또는 HTTPS 프로토콜을 사용합니다.
  • System.Net.Sockets 네임스페이스에 있는 Soket 클래스들 - 이 클래스들은 더욱 범용적인 네트워크 통신을 위해 사용할 수 있는 저수준의 소켓을 제공합니다.

양쪽 모두 보안과 인증되지 않은 접속을 초기화에 대한 보호를 제공할 필요가 있습니다. 다음과 같은 잠재적인 네트워킹 위협은 억제되어야 합니다.

  • 서비스 거부(DoS ; Denial of Service) 공격 - 다수의 원격 호스트가 타겟 사이트를 공격하여 타겟은 정상적인 요청에 대한 서비스를 수행할 수 없게 됩니다.
  • DNS Rebinding 공격 - DNS를 강제로 원격 호스트를 피해자의 IP 주소로 위장하여 신뢰된 호스트(원 사이트site of origin) 이름으로 재 바인딩하여 원래 사이트가 아닌 곳에 있는 호스트가 접근할 수 있도록 사용합니다.
  • 역 터널(Reverse tunnel) 공격 - 원격 클라이언트의 원격지로 나가는 접속을 클라이언트의 내부 네트워크로 들어가는 백 터널로 사용합니다.

실버라이트에 통합된 보안 정책 시스템은 이러한 네트워킹 위협을 막기 위해 디자인 되었습니다. In addition, the policy system also aims to give administrators more control over which resources a remote client is allowed to connect to.(※GG)

과거의 네트워크가능한 플러그인을 위한 디자인은 호스트나 원 사이트(site of origin)로의 접근성을 제한 하였습니다. 이것은 웹 애플리케이션은 오직 그것이 배포된 서버로의 통신만이 가능했다는 것을 의미합니다. 이 보안 모델은 실버라이트 2 베타 1의 소켓 접속에 적용되었고 네트워크 애플리케이션은 그것이 다운로드된 호스트로만 접속할 수 있었습니다.

실버라이트 2 베타 2는 애플리케이션이 원 사이트가 아닌 위치에 있는 리소스를 접근할 수 있도록 크로스-도메인 접속을 위한 지원을 포함합니다. 이것은 실버라이 애플리케이션이 웹에 이미 존재하는 다른 서비스를 사용하기 위한 중요한 기능입니다. 실버라이트 2 런타임의 보안 정책 시스템은 이제 네트워크 접속을 허용하고 리소스에 접근하기 전에 그 네트워크에서 다운로드 된 정책 파일을 필요로 합니다. 이 보안 정책 시스템은 System.Net 네임스페이스에 있는WebClient와 HTTP 클래스의 크로스-도메인 네트워크 접근에도 적용됩니다. 그러나 WebClient와 HTTP 클래스들의 원 사이트 혹은 호스트로의 네트워크 접속은 보안 정책을 필요로하지 않습니다.

소켓의 경우 실버라이트 2 베타 2의 보안 정책 시스템은 원 사이트(site of origin)과 크로스-도메인 네트워크 접근 모두에 다 적용됩니다. 보안 정책은 이제 소켓을 통한 어떠한 접속에도, 심지어 원 사이트로 다시 접속하는 경우라도 필요합니다.

이 섹션에서는 실버라이트 2에서 보안 정책 시스템을 어떻게 사용하는지에 대한 자세한 정보를 제공하고 지원되는 정책 파일 포맷에 대해 설명합니다.

보안 정책 시스템의 기본

실버라이트는 두 종류의 보안 정책 파일을 지원합니다.

  • 플래시 정책 파일 - Adobe 플래시에서 사용하는 crossdomain.xml 정책 파일. 이 정책 파일은 오직 WebClient와 HTTP 클래스에서만 사용 가능합니다. 플래시 정책 파일은 반드시 모든 도메인에 대한 접근을 허용해야 합니다.
  • 실버라이트 정책 파일 - 실버라이트 정책 파일은 WebClient와 HTTP 클래스 및 소켓 클래스에서도 사용할 수 있습니다. 이 정책 파일은 플래시 정책 파일과는 포맷이 다릅니다.

네트워크 리소스에 접속을 허용하기 전에 실버라이트 2 런타임은 네트워크 리소스로부터 보안 정책 파일의 다운로드를 시도할 것입니다. WebClient와 HTTP 클래스에 의한 접속 요청 또는 소켓의 접속에 해당하는 보안 정책을 다운로드 하는 데에는 두 가지 다른 방법이 사용됩니다.

만약 접속 요청이 크로스-도메인 사이트에 대한 WebClient나 HTTP 클래스에서 나왔다면 실버라이트 2 런타임은 HTTP 프로토콜을 사용하여 보안 정책 파일 다운로드를 시도합니다. 실버라이트 2 런타임은 먼저 HTTP 프로토콜을 사용하여 요청된 타겟 도메인의 최상위에 있는 "clientaccesspolicy.xml"이란 이름의 실버라이트 보안 정책 파일의 다운로드를 시도합니다. 만약 실버라이트 정책 파일이 반환되면(심지어 파일의 파싱에 에러가 있더라도) 이것은 실버라이트 애플리케이션의 세션 동안 해당 서버로의 크로스-도메인 요청과  다른 모든 요청을 위한 정책 파일로 사용됩니다. 만약 실버라이트 정책 파일이 발견되지 않으면 실버라이트 2 런타임은 HTTP 프로토콜을 사용하여 요청된 타겟 도메인의 최상위에 있는 "crossdomain.xml"이란 이름의 플래시 정책 파일의 다운로드를 시도합니다. 플래시 정책 파일은 반드시 모든 도메인에 대한 접속을 허용해야 합니다.

만약 접속 요청이 사이트(크로스-도메인이건 다른 사이트이건)에 대한 소켓에서 나왔다면 실버라이트 2 런타임은 TCP를 사용하여 잘 알려진well-known 포트(943번 포트)를 사용하여 대상 사이트로의 접속을 시도합니다. 만약 TCP 접속이 가능하다면 실버라이트 2 런타임은 <policy-file-request/>라는 지정된 문자열을 서버에 보내 실버라이트 정책 파일을 요청합니다. 실버라이트 2 런타임은 이 때 실버라이트 정책 파일을 포함하는 타겟 사이트의 응답의 수신을 대기합니다. 만약 이 실버라이트 정책 파일이 반환되면(심지어 파일 파싱에 에러가 있더라도) 이것은 실버라이트 애플리케이션의 세션 동안 해당 서버로의 소켓 요청과 다른 모든 요청을 위한 정책파일로 사용됩니다.

소켓 클래스를 사용하는데 하나의 추가적인 제약은 네트워크 애플리케이션이 허용된 접속은 반드시 4502-4534 범위의 포트를 사용해야 한다는 것입니다. 소켓을 사용한 실버라이트 애플리케이션의 접속은 오직 이 대상 포트들만 허용됩니다. 만약 대상 포트가 이 포트 범위에 있지 않으면 접속 시도는 실패할 것입니다.

WebClient와 HTTP 클래스에서 사용되는 보안 정책 파일을 배포하려면 시스템 관리자는 정책 파일 정의를 제공하고 실버라이트나 플래시 정책 파일을 HTTP를 통해 전송하기 위해 각 IP 주소별로 웹 서버 설정이 필요합니다.

소켓의 경우 서버에 있는 보안 정책 파일을 배포하기 위해 보안 정책 파일 정의를 제공하기 위하여 각 IP 주소별로 포트 943에 독립된 인증 서비스의 설정이 필요합니다.

실버라이트 정책 파일 포맷

실버라이트 정책 파일 포맷은 다음의 DTD로 설명됩니다.

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- A DTD for the Silverlight Policy File -->
<!ELEMENT access-policy (cross-domain-access)>
<!ELEMENT cross-domain-access (policy+)>
<!ELEMENT policy (allow-from)>
<!ELEMENT policy (grant-to)>
<!ELEMENT allow-from (domain+)>
<!ATTLIST allow-from http-request-headers CDATA>
<!ELEMENT domain EMPTY >
<!ATTLIST domain uri CDATA #REQUIRED>
<!ELEMENT grant-to (resource+)>
<!ELEMENT grant-to (socket-resource+)>
<!ELEMENT grant-to EMPTY>
<!ATTLIST resource path CDATA #REQUIRED>
<!ATTLIST resource include-subpaths (true|false) "false">
<!ATTLIST socket-resource port CDATA #REQUIRED protocol #REQUIRED>
<!-- End of file. --><!-- End of file. -->

다음 표는 사용 가능한 ELEMENT 엔트리를 설명합니다.

엘리먼트
부모 필수 여부 여러 사용 가능 여부 설명
access-policy N/A (root) Yes No 실버라이트 정책 파일의 루트 엘리먼트.
cross-domain-access access-policy Yes No 사이트를 위한 모든 크로스 도메인 정책을 정의.
policy cross-domain-access Yes Yes 지정된 도메인 혹은 도메인의 세트에서의 요청을 위한 크로스 도메인 정책을 정의.
같은 파일 내에 여러 개의 정책이 정의 있음.
allow-from policy Yes No 정책에 의해 영향을 받는 모든 도메인을 정의.
allow-from
엘리먼트를 부분적인 정책으로 사용하여 암시적으로 원치 않는 모든 도메인의 접속을 거부할 있음.
allow-from
비어 있다면 정책 파일은 어떤 사이트에도 접속 권한을 주지 않음.
domain allow-from Yes Yes 정책에 의해 영향 받는 도메인(혹은 지정된 실버라이트 애플리케이션) 정의.
grant-to policy Yes No 정책에 의해 영향 받는 모든 서버의 리소스를 정의.
resource grant-to Yes (for WebClient and HTTP classes) Yes 정책에 의해 접근 가능한 리소스를 정의.
엘리먼트는 오직 WebClient HTTP 클래스를 사용한 접속 요청에만 적용됨.
socket-resource grant-to Yes (for sockets) Yes 정책에 의해 접근 가능한 리소스를 정의.
엘리먼트는 오직 소켓을 사용한 접속 요청에만 적용됨.

다음 표는 각 ELEMENT에서 사용 가능한 어트리뷰트를 설명합니다.

엘리먼트
어트리뷰트 필수 여부 기본값 설명
allow-from http-request-headers No 어떤 헤더도 허용되지 않음( 세트) - domain 어트리뷰트에서 지정된 도메인을 위한 대소문자 구분 없이 콤마(,) 구분된 허용할 헤더의 목록. 문자열은 RFC822 준한 유효한 문자열인 ASCII 33-41, 42-57 59-126. 이것은 콤마(헤더 이름의 끝을 지정) 애스터리스크(와일드카드에 사용되는) 제외한 출력이 가능한 모든 공백이 아닌 ASCII 문자열. 와일드카드는 모든 헤더를 지정하는 사용될 있고 또한 단일 헤더 이름에서 접미사로 사용되어 와일드카드 문자 앞의 문자열로 시작하는 모든 헤더를 허용.
-
일반적인 블랙리스트 헤더를 적용.
-
어트리뷰트가 없을 경우 어떤 헤더도 전송을 허용하지 않음.
domain uri Yes N/A 정책에서 허용된 경로에 접근할 있도록 허용된 도메인과 지정된 실버라이트 애플리케이션의 목록.
'*'
문자는 와일드 카드로 취급되고 모든 것을 허용하도록 처리.
URI
접속을 허용하는 스키마와 도메인을 지정.
resource path Yes (for WebClient and HTTP classes) N/A - 어트리뷰트는 도메인의 루트에 대한 URI. 이것은 서비스 혹은 파일을 나타내는 지정된 경로를 가리킴.
경로는 와일드카드 문자열이나 URI 의해 분석될 없는 캐릭터를 포함할 없음. URI 일반 문법은 http://ietf.org/rfc/rfc3986 참고.

-
엘리먼트와 어트리뷰트는 WebClient HTTP 클래스에서의 요청을 위해서만 사용.
resource include-subpaths No FALSE - 관련 경로가 서브 경로를 포함하는지 여부를 지정.
-
(true) 경우 path 어트리뷰트에 의해 설정된 정확한 경로와 일치하는 경로이거나 일치하는 경로 부분 뒤에 텍스트를 추가하여 요청된 URI 경로를 허용.
-
거짓(false) 경우 오직 path 어트리뷰트에 의해 설정된 정확한 경로만을 허용.
-
엘리먼트와 어트리뷰트는 WebClient HTTP 클래스에서의 요청을 위해만 사용.
socket-resource port Yes N/A - 소켓을 사용하는 애플리케이션의 접속을 허용할 포트 번호 또는 포트 번호의 범위를 지정.
-
엘리먼트와 어트리뷰트는 소켓에서의 요청을 위해서만 사용.
socket-resource protocol Yes N/A - 소켓을 사용하는 애플리케이션의 접속을 허용할 프로토콜을 지정.
-
현재는 TCP 만을 지원.
-
엘리먼트와 어트리뷰트는 소켓에서의 요청을 위해서만 사용.

하나의 실버라이트 정책 파일이 WebClient와 HTTP 클래스에서의 접속 요청과 소켓에서의 접속 요청을 위한 정책들을 포함할 수 있습니다.

이 정책 파일에서 요청이 유효한지를 결정하는 과정은 다음과 같습니다.

- 요청된 URI의 스키마가 애플리케이션의 원 사이트와 같은가? 그렇지 않다면 요청은 접근을 할 수 없으며 전송되어서는 안됨.

- 요청된 URI의 포트가 애플리케이션의 원 사이트와 같은가? 그렇지 않다면 요청은 접근을 할 수 없으며 전송되어서는 안됨.

- 각 <policy> 엘리먼트에 대해

  • 애플리케이션의 원 사이트의 접근이 허용되었는가? 이것은 명시적인 <policy> allow-from domain 어트리뷰트 혹은 모든 접근의 허용을 말하는 와일드카드 uri 어트리뷰트를 포함한 domain 엘리먼트를 가진 allow-from 어트리뷰트 모두를 허용. 만약 allow-from이 생략되면 기본 동작은 아무도 접근할 수 없게 된다는 점에 주의.
  • policy가 요청된 URI에 대한 접근을 허용하는가?

- 다음 조건 중 하나라도 참이면 요청은 접근이 가능하고 전송되어야 함. 그렇지 않으면 다음 <policy>로 이동.

  • 요청된 URI가 <resource> 태그에 있는 도메인과 경로와 완전히 일치.
  • 요청된 URI가 <grant-to> 태그에 있는 도메인과 경로 아래에 위치해 있고 <grant-to> 태그의 include-subpaths 어트리뷰트가 참으로 설정됨.
  • 소켓 요청의 경우, 이 <policy>의 <grant-to> 섹션에 있는 <socket-resource> 태그에서 프로토콜과 포트를 TCP와 4502-4534 범위에 있는 허용된 퍼트 범위로 설정함.

WebClient와 HTTP 클래스를 위한 정책 파일 예제

다음은 WebClient와 HTTP 클래스를 사용한 크로스-도메인 접속을 위한 실버라이트 정책 파일 예제입니다. 이 정책 파일은 요청 헤더를 제한하고 하위 경로를 허용하지 않습니다.

다음은 다른 WebClient와 HTTP 클래스를 사용한 크로스-도메인 접속을 위한 실버라이트 정책 파일 예제입니다. 이 정책 파일은 요청 헤더를 허용하고 하위 경로를 포함합니다.


다음은 또 다른 WebClient와 HTTP 클래스를 사용한 크로스-도메인 접속을 위한 실버라이트 정책 파일 예제입니다. 이 정책 파일은 지정된 요청 헤더를 지정하고 있습니다.


소켓을 위한 정책 파일 예제

다음은 소켓을 사용한 접속을 위한 실버라이트 정책 파일의 샘플입니다.


소켓을 위한 정책 서버의 샘플 코드

다음은 매니지드 코드로 소켓을 위한 간단한 정책 서버를 구현하는 샘플입니다. 샘플 정책 서버는 서버가 시작되었을 때 인자로서 사용할 정책 파일의 이름을 요구 합니다.


※ 이 문서에서는 언급하지 않았지만 소켓을 통한 정책 파일 교환은 위와 같이 서버측에 943번 포트에서 정책 파일을 전송할 서비스를 만들어야만 가능합니다. 자세한 것은 Mike SnowsTip of the Day #12 - Full Implementation of a Silverlight Policy Server.를 참고하세요.

참조

네트워킹과 통신
실버라이트 2의 URL 접근 제약 (번역 : http://gongdosoft.com/293)
소켓으로 작업하기

Posted by gongdo

Submit comment.

  1. Favicon of http://gilverlight.net BlogIcon 길버트 2008.06.30 06:58  comment URL  Edit/Remove  Submit comment.

    와우! 분량이 상당하네요. 수고하셨습니다.

먼저 실버라이트를 하면서 항상 느끼는 건 정말이지 보안에 대해 편집증 적으로 철저하다는 점인데요. 물론 이게 실제 사용에서는 불편이 되겠지만 수 많은 보안 위협에 대해 효과적인 대응이 가능하다는 점에서 감수해야 할 것 같아요. 뭐 당연한 얘기지만 개방 플랫폼이 될 수록 보안적으로 민감한 리소스 접근은 제한이 더 걸릴 수밖에 없으니까요.

그런 점에서 이 문서도 쓸데 없으리만치 장황하게 접근 제약에 대해 명확한 표현을 사용하고 있는데요, 긴 문장 다 읽을 필요 없이 서두와 정리된 표를 참고하시는 게 좋을 것 같네요.


※ 이 문서는 MSDN의 URL Access Restrictions in Silverlight 2를 번역한 것으로 실버라이트2 베타2를 기준으로 합니다. 추후 변경사항이 있을 경우 업데이트 하겠지만 기본적으로 위의 문서를 참고하세요.

보안상의 이유로 실버라이트 버전 2 런타임은 System.Net 네임스페이스에 있는 WebClient와 Http 클래스들에서 사용되는 URL의 접근을 제한합니다. 비슷한 접근 제약이 실버라이트 2 런타임에 의해  System.Windows.Controls 네임스페이스에 있는 ImageMediaElement 클래스를 포함하는 다른 클래스들에도 적용됩니다. 실버라이트 2 런타임은 또한 XAML 소스 파일과 URL의 클래스에 기반한 폰트 파일에도 접근 제약을 적용합니다.

커넥션은 크로스-존, 크로스-도메인 및 크로스-스키마 URL에 접근할 때 적용받습니다. 이 제약들은 네트워킹의 위협(예를 들어, 인터넷 서버에서 실행된 실버라이트 2 기반 애플리케이션이 로컬 인트라넷에 있는 리소스에 접근하는 위협 등)을 막기위해 디자인 되었습니다.

일반적인 URL 클래스들은 다음과 같습니다.

  • 크로스-스키마Cross-scheme URL : 한 스키마(예를 들어 HTTP)를 사용하여 어떤 웹 서버에 있는 한 HTML 페이지로부터 다운로드 된 실버라이트 2 애플리케이션이 같은 서버 혹은 다른 서버에 있는 리소스를 다른 스키마(예를 들어 HTTPS)를 사용하여 접근을 시도할 때.
  • 크로스-도메인Cross-domain URL : 어떤 웹 서버에서 다운로드 된 실버라이트 2 애플리케이션이 다른 타겟 서버에 있는 리소스에 접근(예를 들어 www.gongdosoft.com에 호스트된 애플리케이션이 www.gongdosoft.net에 있는 컨텐츠에 접근을 시도하는 경우)을 시도할 때. 실버라이트 2 런타임은 일반적으로 타겟 서버로부터 이 접근을 허용할지를 결정하는 보안 정책 파일을 다운로드 하여 사용합니다.
Note:
실버라이트 2상에서 크로스 도메인 리소스를 접근할 수 있습니다. 그러나 보안 정책 파일에 명시적으로 활성화 할 필요가 있습니다. 자세한 정보는 실버라이트 2에서의 네트워크 보안 접근 제약 토픽을 보세요.

  • 크로스-존Cross-zone URL : 인터넷 익스플로러는 각각의 영역zone에 적용되는 보안 레벨을 가진 보안의 컨셉을 정의합니다. 여기에는 인터넷, 로컬 인트라넷, 신뢰된 사이트, 제한된 사이트의 네 영역이 정의되어 있습니다. 거기에 더해 로컬 머신은 또 다른 영역으로 고려됩니다. 크로스-존 URL은 어떤 보안 영역에 있는 웹 서버로부터 다운로드 된 실버라이트 애플리케이션이 다른 보안 영역에 있는 타겟 서버에 있는 리소스에 접근을 시도하는 경우를 말합니다. 크로스-존 접근 제약은 인터넷 영역에 있는 서버로부터 다운로드 된 실버라이트 2 애플리케이션이 더 신뢰할 수 있는 로컬 인트라넷이나 신뢰된 영역 및 로컬 머신 영역에 있는 리소스에 접근하는 것으로부터 보호하기 위해 디자인 되었습니다. 이것은 원격 인터넷 서버에서 실행된 실버라이트 2 애플리케이션이 로컬 인트라넷과 다른 리소스에 접근하는 것으로부터 보호를 말합니다. 크로스-존 접근은 타겟 서버에 접근이 허용된 리소스일지라도 막힙니다. 크로스-존 접근은 로컬 인트라넷 영역에 있는 서버에서 다운로드 된 애플리케이션이 인터넷 서버에 있는 리소스에 접근할 때에는 제약받지 않는 다는 점에 주의하세요. 그러나 모든 크로스-도메인 접근이든지 보안 정책 파일을 필요로 합니다. 크로스-존 접근 제약은 윈도우(OS) 상에서 실행된 실버라이트 2 애플리케이션에만 구현되어 있습니다. 보안 영역과 크로스-존 접근의 컨셉은 Apple의 OS X에서 실행된 실버라이트 2 애플리케이션에서는 아직 지원되지 않습니다.

다음 표는 WebClient와 HTTP 클래스들에 사용되는 URL 접근 제약과 다른 실버라이트 클래스 및 컴포넌트에서의 제약들을 포함한 규칙을 정리합니다.

 
WebClient HTTP 클래스 Image 클래스, 프로그레시브 다운로드 MediaElement 클래스(media, images, images, ASX, etc. XAML 소스 파일 폰트 파일 미디어 스트리밍
허용된 스키마 HTTP, HTTPS HTTP, HTTPS, FILE HTTP, HTTPS, FILE HTTP, HTTPS, FILE HTTP
크로스-스키마 접근 허용되지 않음 허용되지 않음 허용되지 않음 안됨 HTTPS에서는 허용되지 않음
크로스-도메인 접근 보안 정책 파일 필요. HTTPS에서 HTTPS라면 허용되지 않음. HTTPS에서 HTTPS 아닐 경우 허용. HTTPS에서 HTTPS 아닐 경우 허용. 허용되지 않음 HTTPS에서 HTTPS 아닐 경우 허용.
크로스- 접근(Windows) 인터넷 영역에서 제한된 영역으로의 접근은 허용되지 않음.
재전송Redirection 허용 여부 같은 사이트와 스키마로는 허용.
크로스-도메인은 보안 정책 파일이 있을 경우만 허용.
같은 스키마일 경우 허용. 허용되지 않음 허용되지 않음 허용되지 않음

Note:
사용자가 이 접근 정책들 중 하나의 위반으로 인한 에러 결과를 받은 경우 에러는 정확한 이유를 가리키지 않습니다.

만약 어떤 웹 서버에 호스트 된 실버라이트 2 애플리케이션을 가지고 있고 WebClient나 HTTP 클래스를 사용하여 이 애플리케이션에서 다른 웹 서버(크로스-도메인 URL)에 저장된 리소스로 접근을 시도하면, 다른 서버가 해당 접근을 명시적으로 허용하도록 만들어진 보안 정책 파일이 없는 한 그 요청은 실패할 것입니다. 윈도우(OS)상에서 만약 인터넷 영역에서 다운로드 된 실버라이트 2 애플리케이션이 보다 제한된 영역(로컬 인트라넷, 신뢰된 사이트 혹은 로컬 머신)에 있는 사이트 URL을 요청할 경우 심지어 가능하도록 된 보안 정책이 있다고 해도 실패할 것입니다. 또한 HTTP 스키마를 사용한 사이트에서 다운로드 된 실버라이트 2 애플리케이션이 HTTP 스키마를 사용하는 타겟 크로스-도메인 사이트를 요청할 경우에도 실패할 것입니다. 또한 HTTPS 스키마를 사용한 사이트에서 다운로드 된 실버라이트 2 애플리케이션이 HTTP 스키마를 사용하는 타겟 크로스-도메인 사이트를 요청할 경우에도 실패할 것입니다.

※ 너무 하나마나 한 소리라 아래의 제약 예제는 생략했습니다.

참조
Posted by gongdo

Submit comment.

SBS 뉴스가 오늘자로 동영상 뉴스 페이지에 실버라이트 기반의 동영상 플레이어를 도입했네요.
사용자 삽입 이미지
바로가기>

기존의 뉴스 페이지에서는 컨텐트를 선택하면 동영상의 캡쳐만 조그맣게 뜨고 '동영상 보기'를 클릭해서 팝업을 띄워서 보는 형태였죠. ActiveX로 구현되어 있어서 어쩔 수 없이 팝업으로 처리를 했던 면도 있을거에요.

이번 뉴스 뷰어는 동영상 뉴스라는 본래의 의미에 맞게 해당 컨텐트를 선택하면 곧바로 페이지 안에 포함된(embed) 형태의 동영상 플레이어를 볼 수 있다는 점에 의의가 있다고 봐요.

물론 그간 소개되어 왔던 rich한 미디어 플레이어에 익숙한 분이라면 아마도 별다른 감흥이 없을 수도 있을거에요. 또 이 전에 소개되었던 NView에 비해서도 많이 단순해졌죠. 저도 몇 가지 사항은 좀 아쉽지만 '뉴스'라는 다소 민감하고 대중적인 컨텐츠를 다루는 특성도 있으니까요. 또한 외적인 면을 중시한 기존의 NView에 비해 뉴스뷰어는 플레이어 본연의 기능에 충실하고 더욱 작은 리소스로 안정적인 동작을 수행하는데 촛점이 맞춰져 있어서 약간 성격이 다르다고 볼 수 있어요.

기술적인 측면에서 현재 SBS의 뉴스뷰어에는 본 동영상이 모두 재생된 후 나가는 후CM과 하단의 텍스트 광고만이 적용되어 있지만 필요에 따라 다양한 형태의 광고를 삽입할 수 있도록 준비되어 있죠.

여튼 방송 3사중 최초로 페이지에 포함된 형태의 실버라이트 동영상 플레이어를 도입했다는 것에 큰 의미가 있고 향후 WMV를 기반으로 미디어 서비스 업계의 실버라이트 도입이 더욱 가속화 될 거에요. 또 SBS에서도 다소 딱딱한 분위기의 뉴스뷰어 뿐만 아니라 실버라이트로 구현된 색다른 서비스를 선보이게 될 거에요. SBS의 더 멋진 서비스를 기대해 봅니다.
Posted by gongdo

Submit comment.

  1. 건태 2008.06.27 15:38  comment URL  Edit/Remove  Submit comment.

    후덜덜 민수 아저씨...^^

PIP는 Picture In Picture의 약어로 보통 영상 매체에서 현재 보고 있는 채널을 바꾸지 않고 다른 채널의 내용을 작게 표시하는 기법을 말하죠.

Remix Korea 08의 마지막 기술 세션에서 이에 관련한 기초적인 내용을 소개했었는데요, 그때 사용한 데모 코드와 PPT 자료를 올리니 참고하시길 바래요.

20080611_Remix08.zip

Remix Korea 08 발표 자료

Remix때는 Demo가 Beta1으로 되어 있어서 그간 공개를 못했는데 Beta2에서도 동작할 수 있도록 포팅을 했고 용량 문제로 MediaExchange/ClientBin/Media 폴더 안에 있는 미디어 파일을 삭제했어요. 그래서 테스트를 하실 때는 그냥 아무 WMV파일 4개를 해당 폴더에 1.wmv ~ 4.wmv 라는 이름으로 넣어야 해요.

혹시 WMV를 검색하기 귀찮으신 분들은 아래의 샘플을 다운받으시면 돼요.
Remix 발표때 사용했던 동영상들이죠.
http://silverlight.services.live.com/59546/Sample1/video.wmv
http://silverlight.services.live.com/59546/Sample2/video.wmv
http://silverlight.services.live.com/59546/Sample3/video.wmv
http://silverlight.services.live.com/59546/Sample4/video.wmv

PIP는 겉보기엔 별로 어려워 보이지 않지만 아무생각 없이 구현했다가는 메인과 서브의 미디어 파일을 바꿀 때 엄청난 시간 지연이 발생하는 낭패를 겪게 되죠.

이 문제를 해결하는 방법을 Demo를 통해 코드로 설명하고 있으니 코드를 찬찬히 뜯어보시면 아마 쉽게 이해하고 적용할 수 있을거에요.

여담으로 오랫만의 사우스파크 얘긴데, PIP 이란 캐릭터 좋지 않나요? ^^;
전에 코미디 센트럴이 사우스파크의 약간의 광고를 포함한 전 에피소드를 웹에서 볼 수 있도록 풀었다는 포스팅을 한 적이 있는데요, 영어가 되시는 분은 http://www.southparkstudios.com/episodes/103918 여기에서 PIP 에피소드를 볼 수 있지요.

Posted by gongdo

Submit comment.

  1. Favicon of http://www.uxkorea.net BlogIcon 준서아빠 2008.06.25 10:39  comment URL  Edit/Remove  Submit comment.

    사팍 매니아... ㅋㅋ
    PIP이 약간 속어가 있는 것으로 알고 있심당... "PIP 이란 캐릭터 좋지 않나요?" 조아조아~

    • Favicon of http://gongdosoft.com BlogIcon 공도 2008.06.25 14:20  comment URL  Modify/Remove

      예... 이 에피소드 말고 닷지볼 하는게 있었는데 어떤 에피소드였는지 기억이 안나네요. 거기서도 PIP이 대활약!

  2. 은가루 2008.08.08 19:03  comment URL  Edit/Remove  Submit comment.

    너무 구경을 하고싶어서 비주얼스튜디오라는것도 깔아봤는데...
    실행이 안되요..ㅜ_ㅜ 어떻게 하면 실행해 볼수있는거죠..ㅜ_ㅜ

이 글로 인하여 잘못된 정보가 전파되질 않길 바랍니다.
자세한 것은 http://gongdosoft.com/290를 참고하세요.

어제 2008/06/12 - [프로그래밍/Silverlight] - [Remix Korea 08] iMBC의 하나더 TV
글에 절망!이라는 트랙백이 붙었는데요, 저는 상당히 우울해졌네요.

쓸데 없는 얘기일지도 모르겠지만, 약간의 변명을 먼저 하자면 그런 정황을 알고 일을 진행했던건 아니에요. 트랙백을 보고 저도 뒤통수를 맞은 기분이었으니까요.

IT업계에서 비일비재 한 일이라고만 생각했었는데 그게 저에게 해당하는 얘기가 될줄은 몰랐네요. 얘기했던 것 처럼 이미 성숙해진 웹 플레이어 애플리케이션에 새로운 모델이나 아이디어를 넣는 다는게 얼마나 힘든일인지 잘 알고 있기 때문에 더 우울해집니다.

개인적으로, 이번 건에 대해 매우 유감입니다.
비즈니스적으로, 혹시 논의할 필요가 있다면 저희 회사로 연락주세요.
아마 제가 생각하는 그 회사가 맞다면 회사도 매우 가까울거에요.

여러모로 심란하네요.
오늘은 다른 곳의 리뷰를 하려고 했는데 당분간 중단합니다.
Posted by gongdo

Submit comment.

  1. Favicon of http://www.oscarplex.net BlogIcon 오스카 2008.06.13 10:24  comment URL  Edit/Remove  Submit comment.

    쩝... 심란하시겠네요. 이 바닥이 뭐 넓은 것도 아니고;;; 잘 해결되길 바랍니다.

  2. Favicon of http://redpin.tistory.com BlogIcon 하영태 2008.06.13 10:29  comment URL  Edit/Remove  Submit comment.

    비즈니스 측면이야 윗 분들께서 알아 하시겠지만 익히 아시다시피 자그만 목소리라도 낼 수 있을런지...^^; 어찌됐든 말씀 중에 공도의 철학이 엿보여 크게 위로가 됩니다. 건승하시기 바라며, 공감해 주셔서 고맙습니다.

  3. Favicon of http://blog.powerumc.kr BlogIcon 땡초 2008.06.13 10:48  comment URL  Edit/Remove  Submit comment.

    자세한 내막은 좀 더 지켜봐야겟지만,
    지금 생각엔 '칼없는 도둑놈이네요' 라밖에,,,
    꼭 건승하세요!!

  4. Favicon of http://blog.naver.com/starcman79 BlogIcon 명군 2008.06.14 23:53  comment URL  Edit/Remove  Submit comment.

    정말 기운 빠지는 얘기네요.
    저도 잘해결되길 바라겠습니다.

    화이팅입니다.

넥슨도 최초의 실버라이트 적용 사례 사이트 중 하나죠.
역시 게임회사 답게 재미있는 애플리케이션을 선보였네요^^

초글링들의 삶의 일부...(^^)


뭐랄까 이건 컨텐츠를 어떻게 만드느냐가 가장 중요할 것 같네요.

개인적으로 리얼한 그래픽의 3D보단 마비노기 같은 카툰 렌더링을 훨씬 좋아하는데 넥슨의 이런 서비스가 실제로 런칭한다면 꽤 재미있을 것 같아요.
Posted by gongdo

Submit comment.

  1. Favicon of http://www.01kim.kr BlogIcon 김영일 2008.06.12 16:43  comment URL  Edit/Remove  Submit comment.

    기대되는 서비스네여
    새로운 컨셉 어떻게 소비자에게 어필이 될지 기대되네여

  2. Favicon of http://taedi.kr BlogIcon 태디 2008.06.13 03:27  comment URL  Edit/Remove  Submit comment.

    어제 PIP 기능 정말 멋졌습니다.
    역시 남보다 한발 앞서 새로운 것을 시도하시는 군요.^^

메가존Remix Korea 08의 홈페이지를 제작한 에이전시죠.


똑같은 실버라이트도 디자이너의 손길이 어떻게 닿느냐에 따라 달라진다는 것을 보여준 대표적인 사례랄까요^^



아마도 개발자와 디자이너와의 협업 문제에 있어서 가장 많은 노하우를 가지고 있을거에요. 역시 언제 한번 놀러가보고 싶네요. ^^
Posted by gongdo

Submit comment.

이번 리믹스에서 KBS 올림픽 방송은 전형적이고 본질적인 라이브 미디어 서비스를 잘 보여줬었죠.


요렇게 여러 라이브 화면을 보고 있다가...


다른 경기의 얼럿이 뜨고 해당 방송으로 즉시 넘어갈 수 있죠.


하이라이트만 모아둔 VOD 모음집. 이런 건 아무래도 터치 인터페이스가 되어야 편리할 듯.

P.S.
흐흐 길버트님, 몇 일 안남겨놓고 떠넘겨서 죄송합니다!
Posted by gongdo

Submit comment.

  1. 길버트 2008.06.12 18:55  comment URL  Edit/Remove  Submit comment.

    아니요, 괜찮습니다.
    재밌었습니다. ㅋㅋ

아마도 WPF/Silverlight 분야를 통틀어 가장 후덜덜한 회사가 아닐까 생각해요.
이노티브의 데모들을 보면서 느껴지는 것은 WPF는 XAML을 사용하는 '언리미티드 빠와~'이고 실버라이트는 그 '리미티드 버전'이라는 것이었죠.
지금은 실버라이트가 WPF가 할 수 있는 엄청난 기능들을 상당부분 제한되어 제공되고 있지만 WPF를 보면서 오히려 실버라이트의 미래상과 가능성을 확신할 수 있게 되는 면도 있죠.

이번에 특히 마음에 들었던건 2D 맵 상에 딥줌과 같은 효과로 무한 줌을 하면서 카메라 및 뷰를 배치한 MapView도 있었지만 역시 더 멋지다고 생각하는 건 건물의 3D투시도에 각각의 CC카메라가 배치되어 있고 그 위치에서 CCTV를 보여주는 데모였어요.

너무 상투적인 표현이지만, 정말로 영화에서나 나올 것 같은 비주얼과 임팩트가 바로 지금! 상용 애플리케이션으로 구현이 된다는 거죠.

기술적으로 봤을 때 WPF는 Photosynth, 딥줌의 전신인 Sea Dragon, Surface 등 LAB에서 만들어진 컨셉추얼한 기능들이 매우 빠르게 수용되는 점이 굉장히 매력적이고 실버라이트는 비록 기능은 더 약하더라도 오히려 WPF보다 한발짝 앞서서 이런 서비스들을 웹 상에 대중적으로 사용할 수 있도록 한다는 것이 큰 매력이고요.

사진 찍은게 없어서 좀 썰렁하네요;; 아마 사진은 길버트님이 잘 정리해서 올려주실 거라 믿어요;

[사진 추가]


행사장을 라이브로 보여주고 있는 CCTV 포인트들... 이게 딥줌처럼 자유롭게 줌인/줌아웃되죠!!




제가 봤을 때 제일 멋졌던 3D화된 CCTV 내비게이션...
그야말로 영화에서나 보던 장면 아닌가요!


P.S.
언제 이노티브에 놀러가면 데모 직접 만져 볼 수 있을까요? 쵝오!!!
Posted by gongdo

Submit comment.

  1. Favicon of http://blog.naver.com/ivoryguard BlogIcon ivoryguard 2008.06.12 12:11  comment URL  Edit/Remove  Submit comment.

    직접 뵈어서 너무 좋았구요....

    여러가지 질문에 대해서 상세히 답변주셔서 감사합니다.

    다음에도 뵐 수 있으면 좋겠네요

  2. 김대희 2008.06.16 15:44  comment URL  Edit/Remove  Submit comment.

    좋은 평 해주셔서 고맙습니다. 언제든 놀러오세요..데모 준비해 놓고 있겠습니다. ^^

이번 Remix Korea 08 미디어 부분에서 가장 의미가 컸던 것은 바로 iMBC의 하나더 TV라고 생각해요. 사실 대중적으로 소비되는 미디어 서비스...라는 게 미디어 플레이어 + 광고 외에 생각할 수 있는게 거의 없고 그 중에서도 미디어 플레이어 부분은 작년 리믹스에서 발표된 MNet의 TVDeep의 임팩트 덕에 '더 이상 나올게 없다'라는 소리를 들을 정도로 차별화하기가 어려운 부분이죠.

iMBC의 하나더 TV는 VOD 서비스에 보다 '의미 있는' 정보를 mix-up하여 일종의 2차적인 컨텐츠 생산이 가능한 구조를 가지고 있죠. 예를 들어 드라마를 보다가 윤은혜가 차고 있는 목걸이는 어디거지? 공유가 타고 있는 자동차는 어떤 기종이지? 저기 촬영 장소는 어디지? 하는 질문들을 흔하게 하죠. 보통은 댓글 같은 걸로 사람들이 알려주거나 조금 더 나은 서비스로는 장면 댓글 이란걸로 남기기도 하겠지만 결정적으로 정보의 신뢰성에 문제가 있을거에요.

제가 앞에서 '의미'를 강조한 이유는 하나더 TV는 각 장면에 상품, 위치, 음악, 영화, 인물, 뉴스, 리뷰 등 보다 의미 있고 신뢰성 있는 정보를 실제 제작진과 관련 업체가 직접 제공할 수 있기 때문이죠. MBC와 같은 미디어 컨텐츠의 생산자들은 이미 그런 방대한 정보를 가지고 있으니까요.

그러나, 이 서비스가 향후 어떤 방식으로 제공될지에 대해 아직 정식으로 런칭되거나 어나운스 되지 않았기 때문에 제가 멋대로 상상의 나래를 펼쳐서 설명하긴 무리가 있으니깐 제 의견은 여기까지만 할께요. ^^

여튼, 하나더 TV가 리믹스에서 발표한 내용이 지금 당장 적용될 수는 없겠지만, 차차 더 멋지게 다듬어진 서비스로 런칭될 수 있길 바래요.



그리고 리믹스를 위해 3주간 빡빡한 일정에 많은 분들이 고생하셨는데요,
특히, 멋진 기획안과 전반적인 커뮤니케이션을 잡아주신 박현경 대리님과 두서 없이 이 이미지 저 이미지 만들어달라는 부탁을 잘 들어주시고 멋진 디자인 시안을 정말 빠르게(!) 만들어주신 김현진 과장님께 감사드리고 결국 제대로 못써먹은 서버측 데이터를 만들어주신 권지혜 대리님 정말 아쉽네요^^;;

모두 수고 많으셨습니다!
Posted by gongdo

Submit comment.

  1. Favicon of https://gilverlight.tistory.com BlogIcon 길버트 2008.06.12 11:08 신고  comment URL  Edit/Remove  Submit comment.

    이름 바꿔야 될 거 같아요~ 열개 더 티비로 ^^
    회사에서 매일 숙식하던 공도님 수고하셨어요!

  2. Akari 2008.06.12 14:18  comment URL  Edit/Remove  Submit comment.

    아쉽게 REMIX에 참관을 못했는데.. 포스팅을 보니 하나더 TV는 매우 관심이 가네요. ^^
    관련 스크린샷이나 데모를 더 보고 싶은데 어디서 더 볼수 있을까요? ^^;

    • Favicon of https://gongdosoft.com BlogIcon gongdo 2008.06.12 14:45 신고  comment URL  Modify/Remove

      리믹스에서 발표된 것은 어디까지나 컨셉추얼한 내용이라서 따로 공개되지는 않고요, 아마도 동영상이 금방 올라올거에요.

  3. Favicon of http://www.uxkorea.net BlogIcon 준서아빠 2008.06.12 18:17  comment URL  Edit/Remove  Submit comment.

    수고 많으셨습니다. 알쥐?

  4. Favicon of http://blog.naver.com/habaro BlogIcon jjin 2009.04.16 09:32  comment URL  Edit/Remove  Submit comment.

    iMBC 김현진입니다.정말 고생많으셨습니다.
    신의손 공팀장님이 아니었으면 절대 완성될수없었던 프로젝트였죠~
    잦은야근에 퀭해진 모습이 늘 안쓰러웠는데 이젠 좀 휴식취하실수 있으실런지..ㅎㅎ
    앞으로의 실서비스때도 많이 도와주세요~^^감사합니다~

  5. hyun 2009.07.22 14:42  comment URL  Edit/Remove  Submit comment.

    매우매우 촉박한 일정을 너무너무 잘 소화해주신 공팀장님, 정말 고생많으셨어요~
    오늘은 좀 쉬실 줄 알았는데... 아침부터 또 부지런히 포스팅을...^^
    제가 곧 리믹스 키노트의 하나더TV 관련 동영상을 공개해 드릴께요.

왔구나아아~~
그런데 REMIX KOREA08 때문에 베타1으로 삽질중이란거... ㅠ.ㅜ

커밍 쑤~운...

P.S.
이과장님 역시 빠르셔!
http://cafe.naver.com/mssilverlight/2475
Posted by gongdo

Submit comment.

  1. REMIX08 2008.06.07 19:01  comment URL  Edit/Remove  Submit comment.

    흑.. S.L2 베타2 설치 시 문제로 지금 다른 방법을 찾고 있습니다.
    REMIX KOREA08사이트 관리자로서 열심히 방법 찾는 중입니다.

    관심 가져주셔서 감사합니다.

    • Favicon of http://gongdosoft.com BlogIcon 공도 2008.06.07 22:20  comment URL  Modify/Remove

      베타가 참 여러사람 고생시키죠? ^^

    • Favicon of http://taedi.kr BlogIcon 태디 2008.06.10 03:16  comment URL  Modify/Remove

      엇그제 발표된버전 VS2008 한글판은 설치안되요...
      이번주에 한글전용 공개된다고 합니다.

      http://blogs.msdn.com/bkchung/archive/2008/06/07/silverlight-2-2.aspx

약간 뒷북성이지만, 휴즈플로우 서퍼들은 REMIX SEA 08에 발표자로서(!) 참가중이에요.
지금쯤 한참 발표하고 있을 시간이네요.
안타깝게도 저는 다른 일 관계로 회사를 지키고 있죠. 가고 싶었는데 ㅠ.ㅜ

세션 페이지에 보면 마지막 쯤에 The Flow of Silverlight in Korea라는 주제로 길버트님과 박스마일님의 발표가 준비되어 있죠.

여담으로 플로우 서퍼들은 피터씨가 만든 신나는 디자인의 티셔츠를 맞춰 입고 갔지요^^

앞면, 신나지 아니한가!


뒷면, Shiverlight.net의 상징과도 같은 발바닥ㅋㅋ

이 티셔츠들은 한국 리믹스에서 한정 수량(!) 뿌릴 예정이니 기대하세요^^
고고씽~
Posted by gongdo

Submit comment.

  1. Favicon of http://www.uxkorea.net BlogIcon 준서아빠 2008.05.30 01:28  comment URL  Edit/Remove  Submit comment.

    한정수량... 탐나는군... ㅎㅎㅎ
    좋은 하루~

  2. Favicon of http://fgnfghdfgkeiyutytr BlogIcon qkqhrud 2008.05.30 15:55  comment URL  Edit/Remove  Submit comment.

    여~옷 디자인한번 쥑이네~~~

  3. Favicon of http://blog.naver.com/outsider14 BlogIcon 정선영 2008.06.03 20:59  comment URL  Edit/Remove  Submit comment.

    정말 갖고 싶은데 어떻게 안될까요?

  4. Favicon of http://zzangmyon.tistory.com BlogIcon 짱묜 2008.06.11 00:31  comment URL  Edit/Remove  Submit comment.

    앗~ 티 너무 이쁘당!!! ㅠㅠ 휴즈플로우 쳐들어가서..들고 튀면 안될까요? ㅋㅋ

  5. Favicon of http://blog.naver.com/sttora2 BlogIcon 홍군 2008.06.13 08:28  comment URL  Edit/Remove  Submit comment.

    어.. 저도 저 티셔츠 받고싶었는데요 ㅎㅎ 결국 사이즈 예측 착오로 ㅋㅋ

    아참 공도님 전 그날 임시계약직 리포터였던ㅠㅠ 1기 MSP 홍군입니다
    그날 제 난감한(?) 인터뷰 적극적으로 임해주셔서 너무X1000 감사드려요 흑흑

    • Favicon of http://gongdosoft.com BlogIcon 공도 2008.06.13 09:34  comment URL  Modify/Remove

      오 반가워요.
      그날 3일째 날새고 가서 정신이 멍해있었는데 들이대서 당황했잖아요 ㅋㅋ..
      여튼 MSP활동 즐겁게 하시길 바래요.

오랫만에 찾아온 쫄지 마세요 씨~리즈
제목과는 다르게 사실 이 시리즈는 실전에서 어찌할 바를 모를 정도로 당황 할 만한 상황과 해결책에 대한 팁이죠. 그건 그렇고.

방금 잡은 따끈따끈한 버그 한마리.

실버라이트 2의 URI는 참조된 어셈블리의 리소스를 표현할 수 있죠. 그래서 다음과 같이 다른 어셈블리의 리소스로 들어 있는 이미지나 XML, XAML등을 가져올 수 있어요.
<Image Source="/SomeAssembly;component/Image/Foo.png" />
그런데 만약 굵게 표시한 SomeAssembly라는 어셈블리가 존재하지 않을 경우 실버라이트 2 애플리케이션은 일말의 경고도 없이 가차 없이 공포의 '화이트 스크린'을 뿌리며 죽어버리죠.

이게 위의 한줄만 보면 문제가 생기는게 너무나도 당연하지만 생각해보세요, XAML은 그야말로 엄청난 길이의 코드로 이루어지게 되는데 프로젝트 도중에 무심코 Copy&Paste 했다가 나~중에서야 동작 테스트에 들어갔다면? 네, 바로 패닉에 빠지게 되는거죠.

오늘의 디버깅 팁(by Boxmile the XAML Expert)
- 실버라이트 애플리케이션이 Exception 없이 죽을 때
- XAML 오류가 날 때
위의 증상이 일어나면...
의심되는 XAML을 전체 주석처리하고 테스트, 다음으로 한줄 한줄씩 주석을 해제 하면서 문제의 원인이 되는 XAML을 찾아보세요.

오늘의 한 마디(by Gilbert)
개발자 망신은 Copy&Paste가 다 시킨다.
Posted by gongdo

Submit comment.

나를 위한 메모.

오늘도 실버라이트로 굿뺑이 나이스뺑이를 치고 있어요.
여튼 평소와 같이 간단한 컨트롤을 하나 만들고 이것저것 하고 있는데, 이상하게도 겨우 50개의 컨트롤을 올리는데 로딩시간이 5초 이상 걸리는거에요. 물론 약간 복잡한 형태를 담고 있는 컨트롤이긴 하지만 아무리 생각해도 이건 아니었죠.

해결하기 위해 별 짓을 다 해봤어요. 컨트롤 안에 있는 무거운 구성요소(이미지, 스토리보드)들을 싸그리 주석처리 하고 다시 해보기도 하고 배경에 있는 다른 컨트롤들을 주석처리 하기도 하면서요. 그래도 거의 차이가 없더군요.

문제는 바로 RootVisual인 Page 클래스의 생성자 또는 Page의 Loaded 이벤트에서 50개의 컨트롤을 죄다 생성했기 때문이었더군요.

일반적으로 생각했을 때 Loaded 이벤트에서 다수의 컨트롤을 초기화 하는 것은 나쁜 생각이 아니지만 실버라이트 전체 페이지가 로드 될 때라면 얘기가 약간 달라지는 것 같아요.
전체 페이지의 초기화 사이클에서는 플러그인 초기화, 메모리 할당, 템플릿 및 스태틱 리소스 초기화 등 여러가지 일이 동시에 일어나기 때문에 일반적인 상황에 비해서 컨트롤이나 오브젝트의 생성/할당 작업이 훨씬 더 느려지는 걸로 보여요.

결국 이 문제를 해결하기 위해서 50개의 컨트롤을 생성하는 작업을 DispatcherTimer를 사용하여 0.5초 정도 지연 시켜서 했더니 5초 이상 걸렸던 초기화 작업이 거의 1초 이내에 완료가 되더군요.

여튼 실버라이트에서 성능적으로 가장 큰 저하가 일어날 때는 다수의 컨트롤을 한꺼번에 오브젝트 트리에 올릴 때인데요, 항상 대용량 데이터를 올릴 때에는 그 상황에 다른 로딩 작업이 있는지를 잘 생각해야 할거에요.

나중에 시간 여유가 생기면 이러한 차이를 체감할 수 있는 샘플을 만들어보도록 하죠.

Posted by gongdo

Submit comment.

먼저 데모는 다음 파일을 받아보세요.

XmlSerializerTest.zip

XmlSerializer 테스트 프로젝트



실버라이트 애플리케이션이 웹 서버로부터 데이터를 교환 하는 방법에는 몇 가지를 생각해 볼 수 있죠. 웹 서비스, JSON, XmlHttpRequest, 기타 등등...
전 이 중에서 웹 서비스를 즐겨썼는데 왜냐면 웹 서비스는 웹 서비스로 전달되는 데이터 인자를 자동으로 직렬화Serialize하여 SOAP형식으로 만들어주고 데이터를 받을 때에도 서비스 참조만 해주면 자동으로 프락시 클래스를 생성해주기 때문에 서버가 전달해준 데이터 클래스를 클라이언트에서도 그대로 쓸 수 있어서 무지 편리하기 때문이죠.

그러나 웹 서비스는 기본적으로 SOAP의 특성상 데이터 부분 외의 오버헤드가 상당히 심한 편이기도 하고 사람이 직관적으로 이해하기에는 통신 구조가 복잡한 편이라서 간단한 데이터 교환은 단순한 구조의 XML을 만드는 경우도 있죠.

XML을 직접 전송하고 받는 쪽에서 파싱을 하는 과정은 꽤나 귀찮은 작업인데요, 만약 자신이 개발한 서버와 데이터를 교환할 때에는 아주 간단한 방법으로 데이터 클래스를 XML로 직렬화 할 수 있어요.

C#에서는 기본적으로 클래스를 선언할 때 [Serializable] 이라는 어트리뷰트를 추가함으로써 간단하게 해당 개체를 직렬화 할 수 있지만 실버라이트2는 Serializable 어트리뷰트가 제공되지 않죠. 대신 XmlSerializer와 Xml관련 어트리뷰트를 제공하여 비교적 간단하게 직렬화를 구현할 수 있어요.

참고로 XmlSerializer를 쓰기 위해서는 System.Xml과 System.Xml.Serialization 어셈블리를 참조해야 해요.


예를 들어 서버 측에서 DB에서 데이터를 조회하고 다음과 같은 데이터 클래스를 만들었다고 치죠.

public class ArticleData

    {

        [XmlElement]

        public long ID { get; set; }                // ID

        [XmlElement]

        public string Title { get; set; }           // 제목

        [XmlElement]

        public string Content { get; set; }         // 내용

        [XmlElement]

        public string Description { get; set; }     // 주석

        [XmlElement]

        public DateTime RegDate { get; set; }       // 등록 일자

        [XmlElement]

        public int ViewCount { get; set; }          // 조회수

        [XmlElement]

        public string ImageUrl { get; set; }        // 이미지 URL(URI는 사용 불가)

        [XmlElement]

        public bool IsRemoved { get; set; }         // 삭제되었는지 여부

 

        [XmlElement]

        public UserData User { get; set; }          // 사용자 정보

    }

 

    public class UserData

    {

        [XmlElement]

        public string ID { get; set; }              // 사용자 ID

        [XmlElement]

        public string Name { get; set; }            // 사용자 이름

    }


보이는 것처럼 데이터 클래스의 각 프로퍼티에 [XmlElement] 또는 [XmlAttribute] 어트리뷰트를 선언만 하면 일단 준비는 끝. 아주 직관적이게도 [XmlElement] 어트리뷰트가 붙은 프로퍼티는 나중에 XML로 생성될 때 <Element>value</Element>형식으로 표현되고 [XmlAttribute] 어트리뷰트가 붙은 프로퍼티는 <ClassName Attribute="value"></ClassName>형식으로 표현되죠.

여튼 이 데이터 클래스는 XmlSerializer에 의해 직렬화되고 이렇게 직렬화된 문자열은 다음과 같은 XML형태가 되죠.

  <?xml version="1.0" encoding="utf-16" ?>

- <ArticleData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <ID>0</ID>

  <Title>테스트</Title>

  <Content>가나다라 あいうえお 家羅多羅 abcd ♠!@#$</Content>

  <RegDate>2008-05-20T21:32:39.938+09:00</RegDate>

  <ViewCount>100</ViewCount>

  <ImageUrl>images/sample.png</ImageUrl>

  <IsRemoved>false</IsRemoved>

- <User>

  <ID>Gongdo</ID>

  <Name>공도</Name>

  </User>

  </ArticleData>


여기서 문제는 encoding="utf-16"을 실버라이트에서 정상적으로 인식하지 못한다는 점인데요, XML의 인코딩은 utf-8로 설정해야 해요. 바로 다음 코드 처럼요.

// DB나 비즈니스 로직에서 작성된 데이터

ArticleData data = new ArticleData

{

    ID = 0,                 // long

    Title = "테스트",       // string

    Content = "가나다라 あいうえお 家羅多羅 abcd !@#$",  // with unicode string

    Description = null,     // null

    RegDate = DateTime.Now, // DateTime

    ViewCount = 100,        // int

    //Image = new Uri("images/sample.png", UriKind.RelativeOrAbsolute),   // Do not use URI

    ImageUrl = "images/sample.png",

    IsRemoved = false,      // bool

    User = new UserData     // Sub class

    {

        ID = "Gongdo", Name = "공도"

    }

};

 

// 시리얼라이저 작성

XmlSerializer xs = new XmlSerializer(typeof(ArticleData));

string response = null;

 

// 시리얼라이즈 결과를 저장할 스트림

using (MemoryStream ms = new MemoryStream())

{

    // UTF-8 인코딩을 사용하기 위해 XmlTextWriter사용

    using (XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8))

    {

        // 데이터 시리얼라이즈

        xs.Serialize(xtw, data);

        // 기록된 데이터의 처음부터 끝까지 string으로 읽기

        ms.Seek(0, SeekOrigin.Begin);

        using (StreamReader sr = new StreamReader(ms))

        {

            response = sr.ReadToEnd();

        }

    }

}


여튼 이렇게 만들어진 XML 문자열을 응답해주면 실버라이트 측에서는 받은 XML 문자열을 별도의 파싱 코드 없이 XmlSerializer의 역직렬화Deserialize를 통해 데이터 클래스로 얻을 수 있어요.

// WebClient XML데이터 Request/Response 처리

WebClient wc = new WebClient();

wc.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)

{

    if (e.Error != null || e.Cancelled)

    {

        // 에러

        return;

    }

    XmlSerializer xs = new XmlSerializer(typeof(ArticleData));

    ArticleData data = xs.Deserialize(e.Result) as ArticleData;

};

wc.OpenReadAsync(uri);


여튼 이 방법은 사실 실버라이트가 [Serializable]을 지원하지 않아서 XSD에 기반한 클래스를 곧바로 사용할 수 없기 때문에 차선으로 선택한 방법이고요, 설계상 썩 좋다고는 할 수 없지만 내가 관리하는 서버와 통신하되 XML로 데이터를 교환하고 싶을 때 아주 유용하게 쓸 수 있는 방법이죠.

Posted by gongdo

Submit comment.

드디어 REMIX Korea 08의 공식 홈페이지가 오픈했습니다!
http://www.visitmix.co.kr/
보면 정말로 고생 하셨을 것 같아요. 언제 한번 만나뵙고 싶네요 ^O^

감각적인 메인 화면
사용자 삽입 이미지

버튼을 클릭하면 멋진 화면 전환이 일어나고 튀어나간 점들의 끝에는...
사용자 삽입 이미지

미디어 파일들이 있군요. 재생해 보면 오른쪽 구석에서 재생중인 비디오가 멋드러지게 비쳐요
사용자 삽입 이미지
페이지 전환 없이 많은 정보를 보여주는데요.
사용자 삽입 이미지

바로 DeepZoom을 활용하고 있죠.
사용자 삽입 이미지

정말 말이 필요 없으니 꼭 들어가보세요! 쵝오 ~~ >_<b
Posted by gongdo

Submit comment.

  1. Favicon of http://loveciel.tistory.com BlogIcon 김시원 2008.05.20 10:28  comment URL  Edit/Remove  Submit comment.

    흐 휴즈플로우의 딥줌 뷰어로 구현되었다면 더 멋졌을텐데요 ^^
    계속 축소시키면 한도끝도 없이 작아지네요 ㅋ

  2. Favicon of http://saturday.tistory.com BlogIcon Saturday 2008.05.20 10:30  comment URL  Edit/Remove  Submit comment.

    우와~ 멋지네요.^^

실버라이트 2는 1.0과는 달리 <object>태그를 사용하여 마치 플래시나 미디어 플레이어를 올리는 것 처럼 쉽게 올릴 수 있게 되어 있고 <object></object> 태그 사이에 원하는 HTML 디자인을 넣어서 실버라이트가 설치되지 않았을 때 화면도 매우 쉽게 구성할 수 있게 되어 있죠.

그런데, 한가지 문제는 이렇게 해서 설치를 마친 후에 자동으로 실버라이트 애플리케이션이 초기화되지 않는다는 점인데요, 이것을 해결하려면 어쩔 수 없이 1.0에서 했던 Silverlight.js와 createSilverlight 함수를 만들어서 사용하는 수 밖에 없어요.

생각해보면 그리 어렵지 않은데 막상 구현하려면 막막한게 사실이죠.
일단 다음 다운 받고 실버라이트 2를 제거한 후 SL2Install_web/SL2InstallTestPage.html 파일을 열어 데모를 실행해볼 수 있어요.
SL2Install.zip

실버라이트 설치 후 자동으로 실행하기 데모


원리는 아주 간단한데요, Silverlight.js에 포함된 Silverlight.isInstalled 함수와 Silverlight.available 및 Silverlight.us.Browser 속성을 사용하여 현재 상태에 따라 처리할 수 있게 했어요. 만약 실버라이트가 설치되어 있으면 정상적으로 생성하면 그만이고, 그렇지 않다면 설치 화면을 보여주고 3초 후에 설치가 완료되었는지를 계속 검사해요. 그러다가 실제로 사용자가 설치 완료하면 다시 한번 실버라이트 생성을 시도하죠.
이러한 역할을 하는 파일이 SL2Install.js인데요, 관심있는 분들은 분석을 해보세요.

단, 이 방법은 IE에서만 작동하는 걸로 알려져 있어요. 아쉽게도 다른 브라우저에서는 자동으로 리프레시 되지 않아서 브라우저를 껐다가 켜야 할 거에요.

사용 방법은 간단해요.
    <div id="silverlightControlHost">
        <div id="silverlightInstall">
            <a href="http://go.microsoft.com/fwlink/?LinkID=108182">
                Microsoft Silverlight 설치하기<br />
                <img src="Silverlight.png" alt="실버라이트 설치" style="border:none 0px #FFFFFF" />
            </a>
        </div>
    </div>
   
    <script type="text/javascript">
        Silverlight.createWithInstall(
            'mySilverlight',
            'ClientBin/SL2Install.xap',
            'silverlightControlHost',
            'silverlightInstall',
            '100%', '100%', null
        );
    </script>

위의 코드에서 굵게 표시된 글자 부분만 체크하면 되는데요,
먼저 silverlightControlHost DIV태그는 실버라이트 애플리케이션이 호스팅될(올라갈) 위치이고,
silverlightInstall DIV는 실버라이트가 설치되지 않았을 때 보여줄 HTML 디자인이에요.
당연히 실버라이트 런타임을 다운받을 수 있는 링크를 연결해줘야 겠죠?
링크는 2.0 beta1의 경우 http://go.microsoft.com/fwlink/?LinkID=108182 이걸 넣어주면 되는데 이 링크는 후에 바뀔 가능성도 염두해야 해요.

마지막으로 위의 두 DIV 태그를 적당한 위치에 배치했으면 HTML의 제일 바닥쯤에 <script>태그를 넣고 Silverlight.createWithInstall(고유ID, XAP위치, HostDIV태그ID, 설치DIV태그ID, 너비, 높이, 유저데이터); 를 호출하면 Host DIV 위치에 실버라이트 애플리케이션이 생성되죠.

피드백 바랍니다. ~ :D
Posted by gongdo

Submit comment.

최근 훈스 닷넷 실버라이트 Q&A에 실버라이트 1.1을 공부해야 하는지 혼란을 느끼시는 분이 질문을 올리셨죠. [관련 게시물]

간략하게 답변했었지만 오해가 있는듯 해서 여기에 다시 생각을 정리해봅니다.

먼저 실버라이트 1.1과 2는 모두 닷넷 프레임워크에 기초하고 있어요. 따라서 자바스크립트만을 사용했던 1.0과는 달리 실버라이트 '닷넷' 프로그래밍을 한다면 당연히 닷넷 프레임워크의 기반 기술을 먼저 익히는 것이 올바른 순서가 되겠죠.

닷넷 프레임워크는 아시다시피 1.0부터 시작해서 1.1, 2.0, 3.0에서 최근의 3.5까지 다양한 메이저/마이너 버전업을 거치면서 진화해왔고 최신 버전이라고 할지라도 과거 버전의 경험과 개념은 충분히 중요한 의미를 가지고 있기 때문에 하위 프레임워크부터 기초를 닦는 게 어쩌면 정석이라고 할 수 있겠죠.

그러나 실버라이트의 1.1 버전은 단언컨대 공부할 필요도 없고 공부해서도 안된다고 생각해요. 실버라이트 1.1의 아키텍처와 기본적인 개념은 물론 '실버라이트'라는 이름 하에 유사하죠. 그러나 실버라이트의 가장 핵심적인 요소라고 할 수 있는 XAML의 구성 요소와 디자인 패턴은 1.1과 2과 '완전히'라고 말해도 좋을 만큼 달라요. 심지어 1.1에서의 경험이 오히려 2에서 사용할 개념들에 접근하기 어렵게 만들수도 있다고 봐요.

더군다나 실버라이트 1.1은 런타임 조차 2와 호환되지 않고 어떠한 지원도 받을 수 없죠. MSDN에서도 1.1이란 단어는 삭제되어 지금은 '존재하지 않는 것'이 되었죠. 즉, 1.1로 뭘 만들어도 보여주는 것 조차 거의 불가능해요.

다시 강조할께요, 실버라이트 1.1은 존재하지 않아요. 다만 1.1에서 테스트되었던 많은 사항들이 완전히 업그레이드 되어 실버라이트 2라는 이름으로 나왔을 뿐이죠. 전에도 한번 포스팅 했지만 만약 지금 당장 한국어화 된 책이 없어서 실버라이트를 공부하기 어렵다면 차라리 WPF를 공부하세요. 실버라이트 2의 아키텍처는 실버라이트 1.1보다는 오히려 WPF를 더 많이 닮아 있고 WPF와 실버라이트는 앞으로 그 발전 방향이 유사할 거에요.

고생해서 책을 썼던 세분도 잘 알고 있어요. 비록 세분 만큼 고생하지는 않았지만 저도 그들과 잠시나마 함께 실버라이트 1.1을 책으로 쓰기 위해 달렸었고 같이 고민했었죠. 그러나 지금 시점에서 1.1이 의미가 없다는 사실은 변하지 않아요.

물론 세분이 쓴 책은 실버라이트 닷넷 프로그래밍 입문자를 위해 C#과 닷넷에 대한 훌륭한 기초 강의도 들어있고 충분히 도움이 되겠죠. 그러나, 저는 단지 C#과 닷넷을 익히는 거라면 그간 수없이 쏟아지고 읽히고 검증된 책들을 선택하겠어요.

너무 강한 어조로 말을 해서 거부감이 들 수도 있을거에요. 그렇지만 이 생각은 실버라이트 1.1로 열심히 뭔가를 만들어봤고 지금은 실버라이트 2를 통해 살아가고 있는 제가 느끼는 바로 그대로에요.

그럼 실버라이트를 공부하는 가장 좋은 방법이 뭐라고 생각하느냐고요?
바로 온라인에 있는 여러 강좌들을 통해 -비록 체계적이지 못하고 얼기설기 엮여 있고 심지어 잘못된 정보가 있을지라도- 간단하게 느껴보고 직접 만들어보고 다른 사람에게 보여주세요. 프로그래밍을 할 때 가장 기쁜 것은 아무리 허접한 쓰레기 같은 프로그램이라도 내가 직접 만들었고 다른 사람에게 보여줄 수 있을 때라고 생각해요. 이 감각을 놓치지 않고 꾸준히 해보는 것이 무엇보다 중요하다고 생각해요. 사람들이 흔히 말하는 '내공'이란 것은 물론 깊이 있는 공부가 필요하겠지만 당장은 중요치 않아요. 우선 시작하세요, 한계를 느끼고 공부를 하는 것은 그 다음이 되어도 좋으니까요.

P.S.
소심해져서 덧을 답니다.
Posted by gongdo

Submit comment.

  1. 자리비움 2008.05.23 02:45  comment URL  Edit/Remove  Submit comment.

    2.0베타1 나온 이후로 한 2주 손댓다가 1.1알파와 2.0베타 비교 후.. 차라리 릴리즈되면 해야겠다라고 잠시 손땐 1인입니다. (사실 정식 나오면 지원될 듯한 컨트롤 만들기 귀찮아서-_-;) 당연히 1.1은 버리는것이 정신 건강에 이롭겠죠; 베타도 아닌 알파를;

    항상 유익한 포스트 잘 보고 배우고 갑니다.
    즐거운 하루 보내시고 화이팅 하세요!

  2. Favicon of http://gaiserne.tistory.com BlogIcon 정환 2008.07.29 19:34  comment URL  Edit/Remove  Submit comment.

    ㅠㅠ 책산 돈이 조금 아까워졋습니다..

전에 네이버 실버라이트 카페에 패러다임님이 올려주신 코드가 있었는데 약간 더 정리해서 #FFFFFFFF 형식과 "Black", "Yellow"같은 표현도 받을 수 있는 확장 메서드 코드를 만들어 봤어요.

---------------------------------------------------------------------------

namespace Hugeflow.Extension.Converter
{

public static class StringConvertExtension

    {

        public static SolidColorBrush ToSolidColorBrush(this string s)

        {

            Color color = Colors.Black;

            Regex reg = new Regex("#([0-9A-Fa-f]{2}){3,4}");

 

            if (reg.Match(s).Success)

            {

                if (s.Length == 7)

                    color = Color.FromArgb(0xFF, Convert.ToByte(s.Substring(1, 2), 0x10), Convert.ToByte(s.Substring(3, 2), 0x10), Convert.ToByte(s.Substring(5, 2), 0x10));

                else if (s.Length == 9)

                    color = Color.FromArgb(Convert.ToByte(s.Substring(1, 2), 0x10), Convert.ToByte(s.Substring(3, 2), 0x10), Convert.ToByte(s.Substring(5, 2), 0x10), Convert.ToByte(s.Substring(7, 2), 0x10));

            }

            else

            {

                var prop = from p in typeof(Colors).GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty)

                           where p.Name.Equals(s, StringComparison.OrdinalIgnoreCase)

                           select p;

                color = (Color)typeof(Colors).InvokeMember(prop.First().Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty, null, null, new Object[] { });

            }

            return new SolidColorBrush(color);

        }

    }

}
---------------------------------------------------------------------------

위의 코드를 새 클래스로 만들어 넣고,
사용할 때에는 다음과 같이 Converter의 네임스페이스를 using으로 선언해 주면 자동으로 모든 문자열에 ToSolidColorBrush라는 이름의 확장 메서드가 보이죠.
---------------------------------------------------------------------------

using Hugeflow.Extension.Converter;

//... 생략...
Brush
brush1 = "#FFFF9966".ToSolidColorBrush();

Brush brush2 = "Yellow".ToSolidColorBrush();
---------------------------------------------------------------------------

코드에 대해 간단하게 설명하자면, 정규식Regular Expressions으로 문자열 형식을 검사하고, 리플렉션Reflection 및 LINQ를 사용하여 실제로 실버라이트에서 사용 가능한 컬러 문자열 형식인지를 검사하여 자동으로 생성하도록 했어요. 뭐, 간단한 코드니까 눈으로 읽어보면 될거에요.

Posted by gongdo

Submit comment.

  1. 네오군 2009.04.28 20:16  comment URL  Edit/Remove  Submit comment.

    감사합니다. 이거 정말 잘 쓰고 있습니다.

실버라이트를 하다보면 어떤 XAML 파일에서 이런 에러를 많이 보게 될거에요.
Object reference not set to an instance of an object
코드에러 지점이 XAML의 첫번째 행으로 잡혀있고 어떠한 힌트도 주지 않죠.

정말이지 엄청나게 삽질을 하게 될 수도 있는 이 에러의 원인은 주로 단순한 오타에서 비롯되는 경우가 많아요.

바로 몇 분전에 길버트님이 겪었던 문제를 예로 들자면...
<Rectangle Width="30" Height="3 0" Fill="#FF000000" />
별 문제 없어보이죠? 눈썰미가 좋은 분은 금방 찾으셨겠지만 문제의 원인은 Height="3 0"에서 중간에 공백이 들어갔고 XML 파싱에 실패한 것이죠.

특히 편집기를 여기저기 왔다갔다 하면서 하다보면 가끔 원치 않는 키스트로크가 들어갈 때도 있잖아요? 저는 z를 실수로 많이 찍는 편이에요.

앞으로 저 에러를 만나면 쫄지 말고 침착하게 XAML의 오타를 찾아보세요.
Posted by gongdo

Submit comment.

  1. 2008.04.10 18:07  comment URL  Edit/Remove  Submit comment.

    비밀댓글입니다

    • Favicon of https://gongdosoft.com BlogIcon gongdo 2008.04.11 23:21 신고  comment URL  Modify/Remove

      단기로 나오는게 어떻게 그렇게 되는지 제가 묻고 싶을 정도네요;
      dp.Language = System.Windows.Markup.XmlLanguage.GetLanguage("ko-KR");
      이런 방법이 있긴 한데 정상적으로 작동하는 것 같지는 않아요. 해결은 Beta2를 기다려야 할 듯.

  2. Favicon of https://gilverlight.tistory.com BlogIcon 길버트 2008.04.10 22:03 신고  comment URL  Edit/Remove  Submit comment.

    아이 창피해! ^^;
    눈 앞에서 일어나는 일이라면 금방 알아채겠지만,
    책상 위에서 노트북을 앞에 두고 이런 저런 잡일을
    처리하다 보면 나도 모르게 스페이스 같은게 들어가기도
    하더군요. 그렇게 되면 테러!! 억울하죠