오랫만이네요. 이건 이주일 전부터 써야지하고 생각했던건데 너무 오랫동안 묵혀뒀어요.
실버라이트 2에서 가장 많이 달라진 것중 하나는 바로 프로젝트에서의 리소스 파일의 관리와 URI 접근 규칙이죠.

※이 글에서 사용된 내용을 포함하는 샘플프로젝트는 다음의 파일을 다운로드 하세요.

SilverlightResourceFiles.zip

실버라이트 리소스와 URI 테스트 프로젝트


리소스 파일이란 공통으로 사용되는 XAML, XML, 이미지, 동영상, 음악 등 컴파일되지 않는 모든 '비실행(non-executable)' 파일을 말해요. 실버라이트 애플리케이션이 이러한 리소스 파일을 요청할 때에는 URI(Uniform Resource Identifier)라고 하는 형식으로 리소스 파일의 위치를 식별하게 되죠.

실버라이트에서 다루는 리소스 파일은 크게 다음과 같은 네가지로 분류할 수 있어요. 자세한 설명은 각 토픽에서 다루도록 하죠.

  • 리소스(Resource)
  • 컨텐트(Content)
  • Site of origin
  • 절대 URI
※노트
이 글에서 모든 비실행 데이터 파일을 의미하는 리소스 파일과 리소스 파일의 종류를 말하는 리소스를 일반적인 폰트와 이탤릭체로 구분합니다. 이 둘의 의미를 혼동하지 않도록 주의하여 읽어주세요.

이 글에서는 실버라이트에서의 리소스 파일의 종류와 정의 그리고 각각의 URI를 표현하는 방법에 대해 설명합니다. 가능하다면 MSDN의 Resource Files도 함께 참고하세요. 사실 이 글의 핵심은 MSDN의 글과 일치하고 약간의 설명만 추가한거에요.

리소스 파일

리소스 파일은 애플리케이션 어셈블리나 라이브러리 어셈블리에 포함(embedded)되는 비실행 데이터 파일을 말해요. 리소스 파일은 어셈블리에 포함되기 때문에 반드시 프로젝트에 포함되어야 하며 비주얼 스튜디오에서는 다음과 같이 프로젝트에 추가된 파일의 Build Action을 Resource로 설정하여 해당 파일을 리소스 파일로 지정할 수 있어요.

비주얼 스튜디오는 비실행 파일이 추가될 경우  기본적으로 Build Action을 Resource로 설정하게 되죠. 만약 해당 파일이 어셈블리에 포함되는게 아니라 다음에 설명할 다른 리소스 형식으로 설정하고 싶다면 반드시 Build Action을 수정해야 해요.

이렇게 리소스로 추가된 리소스 파일은 어셈블리 내에 포함되므로 같은 어셈블리 내에 있는 코드에서는 별다른 접근자 없이 곧바로 리소스 파일의 상대 URI(relative URI)를 사용하여 접근할 수 있어요. 예를 들어 위의 그림처럼 EmbeddedInApplicationAssembly.png 파일이 프로젝트의 루트에 들어있다면 이 그림 파일을 보여주기 위한 Image 오브젝트는 XAML과 코드 비하인드에서 각각 다음과 같이 표현할 수 있죠.

[XAML]
<Image Source="EmbeddedInApplicationAssembly.png" />

[C#]
Image img1 = new Image();
img1.Source = new BitmapImage(new Uri("EmbeddedInApplicationAssembly.png", UriKind.Relative));

한가지 주의할 점은 리소스 파일은 상대 URI로 표현되므로 만약 이 리소스 파일을 요청하는 코드의 위치가 리소스 파일의 위치와 다를 경우 제일 앞에 슬래시로 시작하는 정확한 상대경로를 적어주는 것이 좋죠. 또 한가지 잊지 말아야 할 것은 실버라이트의 URI 표현에는 상위 경로를 의미하는 '../'이나 현재 경로를 의미하는 './'을 사용할 수 없다는 점이에요. 다음은 슬래시로 시작하는 정확한 상대경로로 URI를 표현하는 방법을 보여줘요.

[XAML]
<Image Source="/EmbeddedInApplicationAssembly.png" />

[C#]
Image img1 = new Image();
img1.Source = new BitmapImage(new Uri("/EmbeddedInApplicationAssembly.png", UriKind.Relative));

여러가지 면을 고려할 때 리소스 파일은 리소스를 관리하기 위한 하나의 폴더에 저장하고 리소스 파일의 URI를 지정할 때에는 반드시 슬래시로 시작하는 정확한 상대경로로 표현하는 것이 실수를 줄일 수 있는 가장 좋은 방법이라고 할 수 있어요.

※노트
현재, MSDN에는 앞에서와 같이 /로 시작하는 리소스 파일에 대한 상대 URI를 지정할 수 있다고 나와있으나 실제로 코드를 만들어보면 런타임 예외를 유발하죠. 앞의 설명에서 '../'이나 ./'을 사용할 수 없다는 것도 맞고 정확한 표현을 위해서 완전한 상대 URI를 써야한다는 설명도 맞지만 불행히도(?) /로 시작하는 단순한 형태의 상대 URI를 리소스 파일에 사용할 수 없으므로 다음에서 설명하는 명시적인 방법을 통한 상대 URI를 사용할 것을 권장합니다.

리소스 파일의 또 한가지 특징은 해당 리소스가 다른 어셈블리에 있어도 그것을 참조할 수 있다는 점인데요, 예를 들어 다음과 같이 다른 프로젝트(즉, 다른 라이브러리 어셈블리)에 있는 리소스가 있다고 생각해 보죠.

이렇게 다른 어셈블리에 있는 리소스 파일은 다음과 같이 요청할 수 있어요.

[XAML]
<Image Source="/SilverlightResourceLibrary;component/EmbeddedInLibraryAssembly.png" />

[C#]
Image img1 = new Image();
img1.Source = new BitmapImage(new Uri("/SilverlightResourceLibrary;component/EmbeddedInLibraryAssembly.png", UriKind.Relative));

/SilverlightResourceLibrary;component/ 부분은 어셈블리의 위치를 명시적으로 표시하는 방법인데요, 위와 같이 다른 어셈블리를 표현할 수도 있지만 자기 자신의 어셈블리를 명시적으로 표현할 수도 있죠. 예를 들어 같은 어셈블리에 있더라도 명시적으로 정확히 리소스 파일을 가져오기 위해 /SilverlightResourceFiles;component/...와 같이 표현할 수 있어요.

앞에서 설명한 것처럼 리소스 파일은 어셈블리에 포함되는데요, 이 사실은 .NET Reflector와 같은 어셈블리 해커를 통해 쉽게 확인할 수 있어요.


컨텐트 파일

컨텐트 파일은 배포되는 패키지에 포함되는(in-package) 비실행 데이터 파일을 말해요. 즉,  XAP 패키지 파일(.XAP)내에 파일의 형태로 포함되는 형태의 리소스를 말하죠. 컨텐트 파일은 비주얼 스튜디오에서 다음과 같이 Build Action을 Content로 설정하여 지정할 수 있어요.

컨텐트 파일도 패키지 내에 포함되기 위해 반드시 프로젝트에 추가되어 있어야 하며 따라서 항상 그 파일이 존재한다고 가정할 수 있어요. 또한 패키지를 기준으로 항상 어셈블리와 같은 경로에 있기 때문에 단순히 상대 URI만으로 해당 리소스를 요청할 수 있죠. 다음은 XAML과 C# 코드로 컨텐트 파일을 요청하는 Image 오브젝트를 보여줘요.

[XAML]
<Image Source="/IncludedInApplicationPackage.png" />

[C#]
Image img1 = new Image();
img1.Source = new BitmapImage(new Uri("/IncludedInApplicationPackage.png", UriKind.Relative));

잊지 마세요, 컨텐트 파일은 코드가 들어있는 어셈블리가 위치한 경로와 컨텐트 파일의 경로가 서로 다를 수 있기 때문에 반드시 위와 같이 슬래시로 시작하는 정확한 상대 URI로 표현해야 해요.

컨텐트 파일은 다음과 같이 애플리케이션 패키지(.XAP)를 압축해제 해 보면 확인할 수 있어요.


Site of Origin

Site of Origin은 딱히 한글로 번역할만한 단어를 찾지 못했는데요, 풀어서 얘기하자면 실버라이트 애플리케이션 패키지를 다운로드한 원래 사이트(같은 도메인에 있는 서버)를 말해요. 즉, Site of Origin 파일은 원래 사이트에 있는 비실행 데이터 파일을 말하죠. Site of Origin 파일은 다음과 같이 비주얼 스튜디오에서 Build Action을 None으로 설정하면 돼요.

또한 Copy to Output Directory 속성을 Copy Always로 설정하면 출력 경로에 해당 파일을 항상 복사하게 되므로 배포가 조금 더 용이해지죠.

※노트
하지만 위와 같이 Copy Always를 설정하더라도 실버라이트와 연결된 웹 사이트나 웹 애플리케이션 프로젝트의 출력 경로에는 해당 파일이 복사되지 않으므로 반드시 다음과 같이 Site of Origin 파일들을 실제 웹 프로젝트의 출력 경로에 복사해줘야 합니다. 이 기능은 다음 베타때 꼭 지원을 해줬으면 하네요.

중요한 것은 Site of Origin 파일은 어셈블리나 패키지에 포함되지 않고 필요할 때마다 다운로드(On-Demand)되므로 실제로 서버에 파일이 존재하지 않을 가능성이 있다는 점이에요. 따라서 Site of Origin 파일을 사용하는 코드는 적절한 이벤트 핸들링을 통해 로드에 실패했을 때 처리를 수행해야 하죠. 그러나 이 글에서는 논의의 범위를 벗어나므로 에러를 처리하는 방법에 대해서는 소개하지 않고 다음에 추가로 포스팅하도록 하죠. Site of Origin 파일은 XAML과 C# 코드에서 다음과 같이 표현할 수 있어요.

[XAML]
<Image Source="/OnDemandAtSiteOfOrigin.png" />

[C#]
Image img1 = new Image();
img1.Source = new BitmapImage(new Uri("/OnDemandAtSiteOfOrigin.png", UriKind.Relative));

한 가지 주의할 점은 Site of Origin에서의 '/'는 일반적인 웹과는 달리 웹 사이트의 루트 경로를 나타내지 않는다는 점이에요. 실버라이트 애플리케이션은 실버라이트 패키지가 배포되는 경로를 기준으로 완전히 독립적으로 작동하며 따라서 '/'는 실버라이트 패키지 즉, XAP파일이 있는 경로를 의미하게 돼요. 또한 앞에서 설명한 것처럼 '../'을 사용할 수 없기 때문에 실버라이트 애플리케이션이 상대 경로를 통해 웹 서버의 다른 리소스를 접근하는 것은 금지되게 되죠.


리소스(or 컨텐트) vs Site of Origin

Application Development Overview에서 다뤘듯이, 애플리케이션 패키지는 가능한 그 크기를 줄이는 것이 빠른 응답을 하는 애플리케이션을 만드는 가장 기본적인 방법이죠. 즉, 애플리케이션 패키지에 포함되는 리소스 파일과 컨텐트 파일은 그 성격과 크기, 종류에 따라 신중하게 선택하는게 좋아요. 각 파일의 선택은 대체로 다음과 같은 기준으로 정할 수 있을 거에요.

  • 리소스 파일
    모든 애플리케이션에 공통적으로 적용될 어셈블리에 포함되는 사용자 컨트롤 등의 표현에 없어서는 안될 에셋(Asset)성격의 이미지, XAML, 효과음 등의 작은 파일
  • 컨텐트 파일
    애플리케이션 마다 다르게 사용될 수도 있는 종류의 스킨, 설정 등의 작은 파일
  • Site of Origin 파일
    애플리케이션의 외형적인 이미지, XAML, 동영상, 음악 등 애플리케이션을 표현하기 위해 필요한 모든 종류의 파일

상대 URI로 표현되는 리소스들은 경우에 따라 애매하게 될 수 있어요. 예를 들어,

"RelativeURIResource.png"

이것만으로는 해당 파일이 리소스인지 Site of Origin인지 구분할 수 없겠죠. 또한,

"/RelativeURIResource.png"

이 경우는 해당 파일이 컨텐트인지 Site of Origin인지를 구분할 수가 없어요.
이런 경우 실버라이트 런타임은 다음의 과정을 통해 파일을 찾게 돼요.

  1. 만약 URI가 /어셈블리이름;component/ 처럼 명시적으로 지정된 경우 해당 어셈블리에서 리소스 파일을 확인하고 없을 경우 이미지 로드 실패
  2. 만약 제일 앞에 /가 없다면 가장 먼저 어셈블리에 해당 리소스 파일이 있는지 확인
  3. 다음으로 패키지가 위치한 Site of Origin에서 해당 파일을 요청하고 존재하지 않을 경우 이미지 로드 실패
  4. 만약 제일 앞에 /가 있다면 가장 먼저 Site of Origin에서 해당 파일을 요청
  5. 다음으로 XAP 패키지에서 컨텐트 파일을 확인하고 없을 경우 이미지 로드 실패
※노트
앞에서 설명한 것처럼 현재 실버라이트의 URI 표현은 뭔가 MSDN과 맞지 않는 부분이 있고 따라서 위의 검색 순서는 다음 베타 버전에서 변경될 가능성이 있으니 주의하세요.

절대 URI

절대 URI는 일종의 Site of Origin이지만 의미상 같은 도메인의 서버 뿐만 아니라 다른 도메인(크로스 도메인)의 리소스도 요청할 수 있다는 점에서 따로 분리했어요. 앞에서 살펴본 세가지 경우와는 달리 절대 URI는 말 그대로 지정된 절대적인 경로에서만 파일을 요청하게 되죠. 또한 절대 URI로 설정할 경우 요청하는 리소스의 종류에 따라 크로스 도메인을 사용할 수 있다는 점에서 앞의 세가지 경우와 다르다고 볼 수 있어요.

절대 URI는 다음과 같은 구성 요소로 이루어져 있죠.

  • 스키마
  • 호스트
  • 포트 번호
  • 경로

예를 들어 gongdosoft.com이라는 웹 서버에 있는 ghost.png라는 파일은 http://gongdosoft.com:80/ghost.png로 표현할 수 있고 각각,

http:// gongdosoft.com :80 /ghost.png
스키마 호스트 포트 번호 경로

로 구분할 수 있죠. 대체로 http-80과 같이 잘 알려진 스키마와 포트는 생략되는게 일반적이에요.

만약 스키마, 호스트, 포트 번호가 실버라이트 패키지의 위치와 다를 경우 접근 정책에 따라 제한을 받을 수 있으며 여기에 관해서는 URL Access Policy를 참고하세요.

절대 URI를 가진 리소스를 요청하는 방법은 다음과 같아요.

[XAML]
<Image Source="http://shiverlight.net/Images/AbsoluteURI.png" />

[C#]
Image img1 = new Image();
img1.Source = new BitmapImage(new Urihttp://shiverlight.net/Images/AbsoluteURI.png", UriKind.Absolute));

절대 URI도 Site of Origin과 같이 필요할 때 요청하는 리소스이기 때문에 리소스를 요청하는 시점에는 존재하지 않거나 요청에 실패하는 경우가 있을 수 있겠죠. 따라서 반드시 로드 실패에 대한 이벤트를 처리해야 한다는 것을 잊지 마세요.


참고


신고
Posted by gongdo
가장 잘 알려진 미국 애니메이션하면 역시 심슨과 사우스 파크일텐데요, 저는 사우스 파크쪽이 더 재밌다고 생각해요. 그건 그렇고.

사우스파크 전 에피소드, 웹상으로 공개
에 의하면 평소 유튭등으로 공공연하게 떠돌던 사우스 파크를 트레이 파커/맷 스톤이 공식 사이트를 통해 오픈해버렸다고 하는군요.
이 멋진 자식들!

http://www.southparkstudios.com/  

자막이 매우 아쉽지만 사우스 파크라면 메모장에 자막 띄워놓고 볼 수 있을 정도죠!

아래는 그냥 하나 찍었는데 나온 Korn 등장 에피소드. 이 장면 처음에 봤을 때 뒤집어졌었는데 말이죠 ㅋㅋㅋ.
사용자 삽입 이미지
Korn Power!!
사용자 삽입 이미지
신고
Posted by gongdo

약간의 경험이 있으시다면 곧바로 팀 스니쓰의 Uploading Silverlight 2 Content to Silverlight Streaming를 참조하시면 되고요^^

먼저 Windwos Live의 실버라이트 스트리밍이 뭔지 짚고 넘어가죠.
실버라이트 스트리밍은 Windows Live 서비스의 하나로 http://dev.live.com/silverlight/에서 제공되는 실버라이트를 위한 무료 호스팅 서비스에요.

Windows Live에서 정의하는 실버라이트 스트리밍은, 무료로 실버라이트 애플리케이션을 배포하기 위한 애플리케이션 호스팅 및 스트리밍 솔루션이죠.

여기에서 무료의 범위는 현재(Beta)상태에서는 한 계정당 10GB의 호스팅 용량인데요, 이정도면 웬만한 웹 애플리케이션은 다 올릴 수 있겠죠. 이용 조건은 호스트에 올릴 수 있는  비디오의 전송 속도는 1.4Mbps이내 그리고 비디오의 길이가 10분을 넘기지 않아야 하고요, 한달 동안의 트래픽은 5TB로 제한되어 있다는군요. 베타 서비스가 종료되면 무제한인 대신 광고가 붙는 호스팅 또는 광고가 없는 수수료 방식의 유료 서비스로 전환되죠. 언제 그렇게 될지는 아직 알 수 없고요.

이미 SDK도 나와 있는데요, http://msdn2.microsoft.com/en-us/library/bb851621.aspx여기를 참고하세요.

자, 그럼 실버라이트 스트리밍을 시작해보죠.

 

먼저 http://silverlight.live.com 에 가서 새 계정을 만들어야죠(Get it free 클릭). 이미 있다면 다음으로...

모든 Windows Live 서비스는 Live ID를 요구하는데요, 실버라이트 스트리밍도 마찬가지죠.

로그인 하면 별다른 과정 없이 곧바로 위와 같은 인증 키가 발급이 되죠. 이것은 향후 API를 이용하거나 할 때 필요하니 꼭 어딘가에 적어두세요. 나중에라도 왼쪽에 보이는 [Manage Account]메뉴를 통해서 재발급 받을 수 있긴 해요.

자 이것만으로도 실버라이트 스트리밍 준비는 끝났습니다. 이제 업로드를 해보죠.

먼저 업로드할 실버라이트 애플리케이션을 만들어야겠죠? 저는 전에 세미나 데모로 사용했던 DeepZoomBase를 골랐어요. 해당 실버라이트 애플리케이션 구동에 필요한 XAP파일과 XAP파일과 함께 배포할 이미지, 미디어 등의 리소스 폴더 그리고 가장 중요한 Manifest.xml 파일을 하나의 ZIP 파일로 압축하면 돼요. Manifest.xml은 다음과 같은 형식으로 만들면 되고요.

<SilverlightApp>
  <version>2.0</version>
  <source>DeepZoomBase.xap</source>
  <width>640</width>
  <height>480</height>
  <background>white</background>
  <isWindowless>false</isWindowless>
</SilverlightApp>

이렇게 모아서 하나의 ZIP으로 압축해두고 다음으로 진행.

Silverlight.live.com에서 [Manage Applciations]를 선택하면 위와 같은 업로드된 Application 목록이 나오는데요, 여기에서 [Upload an application]을 클릭하여 다음으로...

아까 묶어둔 ZIP파일을 선택하고 Upload하고 기다리면 되는데요, 업로드 속도... 장난아니게 느립니다. -_-; 대략 60kbps쯤 나오는 것 같더군요. 인내심을 길러야 겠네요 ㅠ.ㅜ 참고로 한번에 업로드할 수 있는 용량은 105MB가 한계에요.(동영상 파일도 동일)

 

업로드가 완료되면 위와 같이 업로드된 애플리케이션에 대한 관리를 수행할 수 있고 아래쪽에는 이 애플리케이션을 퍼가는 방법에 대한 안내가 나와 있어요. 예를 들어 제가 테스트로 올린 애플리케이션은 http://silverlight.services.live.com/invoke/59546/DeepZoomBase/iframe.html 라는 주소로 접근할 수 있죠.

아쉬운 점은 우선 속도가 그닥 빠르지 않다는 점이고요. 그런데 이 점은 해외에서는 빠르다는 얘길 들었어요(물론 확인은 못했습니다만 -_-)
다음으로 위의 경로로 접속하면 msbluelight-0.agappdom.net/e1/d/59546/1353527/63341546400/0.PLOueqf6XALqnUkPHslm5smtDVQ/zziframehtml2zz.html#%2f%2fappId%2fDeepZoomBase.xap%2fwhite%2ffalse%2f%2f%2f%2f%2ftrue%2f2.0%2f0와 같이 '더러운' 이름의 URL로 redirect되는데요, 이래서야 원 업로드된 XAP파일의 경로를 안다고 해도 XAP파일만 따로 링크를 거는 것은 불가능해지겠죠.

애초에 실버라이트 스트리밍에 올려놓은 애플리케이션은 javascript나 iframe으로 올릴 수 있게 되어 있는데요, 실버라이트 2를 지원하는 김에 XAP파일을 직접 접근할 수 있는 방법을 마련해줬으면 좋겠어요.

그럼에도 불구하고 실버라이트 스트리밍 서비스는 정말로 유용하다고 생각해요. 예전에 저도 실버라이트 1을 할 때 마땅히 올려놓을 계정이 없어서 불안한 무료 계정을 썼었는데요, 만약 실버라이트 데모 저장이나 공유를 목적으로 한다면 실버라이트 스트리밍이 탁월한 선택이 될 것 같네요.

한번 써보시고 멋진 데모들을 만들어서 다른 사람과 공유해보시죠! :D

신고
Posted by gongdo


티스토리 툴바