programming/.net2009.08.06 19:24
IIS 없이 웹서비스를 해야할 일이 생겨서 웹 서버를 만들려구 Socket Server 만들고... HTTP 분석하고 Protocol Parser 만들고 별짓 다 했더만... 
아놔....WCF를 응용하면 되는걸 까맣게 잊고 있었다... ㅡㅡ;;;;
뭐..하지만 Protocol 공부하는덴 도움이 됐던것같다... 어쨌든 부랴부랴 WCF로 웹서버를 만들고 테스트 해보니 잘 동작했다.

기능을 몇개 추가하면 동적웹페이지도 구현하기 쉬울 것 같다..

[WCFWebServer.cs]
  1. using System.Text;  
  2. using System.IO;  
  3. using System.ServiceModel.Web;  
  4. using System.ServiceModel;  
  5. using System;  
  6. using System.ServiceModel.Description;  
  7.   
  8. namespace Utils  
  9. {  
  10.     // 참고: 여기서 클래스 이름 "WCFWebServer"를 변경하는 경우 App.config에서 "IWCFWebServer"에 대한 참조도 업데이트해야 합니다.  
  11.     public class WCFWebServer : IWCFWebServer  
  12.     {  
  13.         private static ServiceHost wcfhost;  
  14.         private static string rootPath;  
  15.         private static int port;  
  16.   
  17.         /// <summary>  
  18.         /// WCF객체 생성을 위한 기본 생성자  
  19.         /// </summary>  
  20.         public WCFWebServer() : base()  
  21.         {  
  22.         }  
  23.   
  24.         /// <summary>  
  25.         /// 생성자  
  26.         /// </summary>  
  27.         /// <param name="_rootPath"></param>  
  28.         /// <param name="_port"></param>  
  29.         public WCFWebServer(string _rootPath, int _port)  
  30.         {  
  31.             rootPath = _rootPath;  
  32.             port = _port;  
  33.         }  
  34.   
  35.         /// <summary>  
  36.         /// 서비스를 시작한다.  
  37.         /// </summary>  
  38.         public void Start()  
  39.         {  
  40.             //Setting WCFHost  
  41.             string baseAddress = string.Format("http://{0}:{1}", Environment.MachineName, port);  
  42.             wcfhost = new ServiceHost(typeof(WCFWebServer));  
  43.             WebHttpBinding binding = new WebHttpBinding();  
  44.             binding.TransferMode = TransferMode.Streamed;  
  45.             wcfhost.AddServiceEndpoint(typeof(IWCFWebServer), binding, baseAddress).Behaviors.Add(new WebHttpBehavior());  
  46.             wcfhost.Open();  
  47.         }  
  48.   
  49.         /// <summary>  
  50.         /// 서비스를 중지한다.  
  51.         /// </summary>  
  52.         public void Stop()  
  53.         {  
  54.             if(wcfhost != null)  
  55.                 wcfhost.Close();  
  56.         }  
  57.   
  58.         /// <summary>  
  59.         /// Web 경로의 파일을 반환한다.  
  60.         /// </summary>  
  61.         /// <returns></returns>  
  62.         public Stream GetFile()  
  63.         {  
  64.             string filename = rootPath + WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.LocalPath;  
  65.   
  66.             //Root 처리  
  67.             if (WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri.LocalPath == "/")  
  68.                 filename = MDIMain.dsATTVData.Option[0].cciPath + "\\default.html";  
  69.   
  70.             if (File.Exists(filename))  
  71.             {  
  72.                 Stream stream = (Stream)new FileStream(filename, FileMode.Open, FileAccess.Read);  
  73.                 string extension = Path.GetExtension(filename);  
  74.                 switch (extension)  
  75.                 {  
  76.                     case "jpg":  
  77.                         WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";  
  78.                         break;  
  79.                     case "png":  
  80.                         WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";  
  81.                         break;  
  82.                     case "gif":  
  83.                         WebOperationContext.Current.OutgoingResponse.ContentType = "image/gif";  
  84.                         break;  
  85.                     case ".html":  
  86.                     case ".htm":  
  87.                         WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";  
  88.                         break;  
  89.                     case ".css":  
  90.                         WebOperationContext.Current.OutgoingResponse.ContentType = "text/css";  
  91.                         break;  
  92.                     default:  
  93.                         WebOperationContext.Current.OutgoingResponse.ContentType = "*/*";  
  94.                         break;  
  95.                 }  
  96.   
  97.                 return stream;  
  98.             }  
  99.             else  
  100.             {  
  101.                 //File이 없을 경우  
  102.                 WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";  
  103.                 string msg = "<b>File Not Found.</b>";  
  104.                 Stream ms = new MemoryStream(Encoding.ASCII.GetBytes(msg));  
  105.                 return ms;  
  106.             }  
  107.         }  
  108.     }  
  109. }  


[IWCFWebServer.cs]
  1. using System.ServiceModel;  
  2. using System.IO;  
  3. using System.ServiceModel.Web;  
  4.   
  5. namespace ATTV.Lite.Utils  
  6. {  
  7.     // 참고: 여기서 인터페이스 이름 "IWCFWebServer"를 변경하는 경우 App.config에서 "IWCFWebServer"에 대한 참조도 업데이트해야 합니다.  
  8.     [ServiceContract]  
  9.     public interface IWCFWebServer  
  10.     {  
  11.         [OperationContract, WebGet(UriTemplate="*")]  
  12.         Stream GetFile();  
  13.     }  
  14. }  


WCF host객체의 TransferMode를 Streamed로 한 이유는 동영상 Stream기능이 필요해서 설정했다.
차암~~쉽군..
Posted by 귀뫄뉘
TAG ,

댓글을 달아 주세요

  1. 안녕하세요^^;
    WCF을 이용해 영상 stream 기능을 구현 하려고 하는데 자문 좀 구하고 싶어서요...^^;

    [binding.TransferMode = TransferMode.Streamed]

    요것이 Stream 형태로 보내라고 설정한 건가요??
    [WCP stepbystep] -> 요책 보고 있는데... 이렇게 하기만 하면... 알아서 쪼개서 보내주는건가요?

    2010.09.02 18:19 [ ADDR : EDIT/ DEL : REPLY ]
  2. 단방향 설정... 요런거 해야하나요?? 스트리밍으로 영상을 계속 쏘려면 상대가 받았는지 않받았는지 기다리면 안되는거 아닌가요??

    2010.09.02 18:23 [ ADDR : EDIT/ DEL : REPLY ]
  3. 안녕하세요? 요즘 제가 닷넷을 안한지 오래되서 잘은 모르겠는데...

    Streamed로 보내면 wcf 메세지에서 헤더부분을 제외한 몸통부분이 스트림으로 가는게 맞습니다. 쪼개서 보낸다는 의미를 잘 모르겠지만.. 버퍼메모리를 사용하지 않고 클라이언트에 전송하는 거죠..
    단방향.. 이건 잘 모르겠네요..

    근데 영상스트리밍은 WCF로 구현하기엔 한계가 있어요.. 위 코드에서 Streamed란 영상스트림 같은게 아니고 기본적으로 HTTP에서 프로그래시브 다운로드와 동일합니다.. 단지 서버입장에서 버퍼메모리를 사용하냐 마냐에 따른 (이에따라 서로다른 제약이 생기겠지만..) 선택인걸로 알고 있습니다..

    그리구 이건 제가 테스트해보다가 말아서 정확하진 않는데.. 일단 Streamed로 선택하고 영상을 play시키면 잘 되긴 합니다..(물론 Buffered로 설정해도 잘 됩니다.. progressive download니까.. ㅎㅎ) 근데 한 유저가 영상을 받는중에 다른 유저가 또 접속하려 하면 접속이 안됩니다.. 즉 이전에 접속한 유저가 전송을 끝낼때까지 다른 유저는 대기하게 됩니다.. 한 유저만 접속할 수 있어요.. 이건 buffered 방식도 동일한건지는 잘 모르겠네요.

    이 이상은 잘 모르겠네요.. wcf가 깊게 알기엔 너무 방대한 양이라..

    2010.09.03 14:16 신고 [ ADDR : EDIT/ DEL : REPLY ]
  4. 친절한 답변 감사드립니다..ㅠㅠ

    좋은 하루 되세요^^

    2010.09.06 11:44 [ ADDR : EDIT/ DEL : REPLY ]