성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] How can I tell whether two programs...
[정성태] The case of the fail-fast crashes c...
[정성태] Creating Docker multi-arch images f...
[정성태] BinaryFormatter removed from .NET 9...
[정성태] Extending the Windows Shell Progres...
[우광현] 와..... 범위를 잡았으니 클라이언트가 해당 범위를 확인해본다...
[정성태] 딱히, 그것 이상으로 더 설명할 내용이 없습니다. 동적 포...
[정성태] If Windows 3.11 required a 32-bit p...
[정성태] What is a hard error, and what make...
[괴물신인] 질문작성자인데 이 글을 이제봤네요 ㄷㄷ 이 글처럼 타입별로 인...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>OWIN 웹 서버(EXE)를 IIS에서 호스팅하는 방법 - HttpPlatformHandler (Reverse Proxy)</h1> <p> 지난 글에서 일반적인 웹 서버를 IIS에서 호스팅하는 방법을 살펴봤습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 사용자 정의 웹 서버(EXE)를 IIS에서 호스팅하는 방법 - HttpPlatformHandler (Reverse Proxy) ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11434'>http://www.sysnet.pe.kr/2/0/11434</a> </pre> <br /> 그런데, OWIN으로 만든 웹 서버의 경우 HttpPlatformHandler를 이용해 호스팅하는 경우 w3wp.exe의 자식 프로세스로 웹 서버 EXE가 살았다 죽었다를 빠르게 반복하다가 결국 웹 브라우저에서는 다음과 같은 오류 메시지만을 보게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>HTTP Error 502.3 - Bad Gateway</span> There was a connection error while trying to route the request. Most likely causes: * The CGI application did not return a valid set of HTTP errors. * A server acting as a proxy or gateway was unable to process the request due to an error in a parent gateway. Things you can try: * Use DebugDiag to troubleshoot the CGI application. * Determine if a proxy or gateway is responsible for this error. Detailed Error Information: Module httpPlatformHandler Notification ExecuteRequestHandler Handler httpplatformhandler Error Code 0x8007065f Requested URL http://localhost:8094/ Physical Path D:\owin_core Logon Method Anonymous Logon User Anonymous More Information: This error occurs when a CGI application does not return a valid set of HTTP headers, or when a proxy or gateway was unable to send the request to a parent gateway. You may need to get a network trace or contact the proxy server administrator, if it is not a CGI problem. </pre> <br /> 아울러 이벤트 로그에는 다음의 메시지들을 확인할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > The description for Event ID 1000 from source HttpPlatformHandler cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer. If the event originated on another computer, the display information had to be saved with the event. The following information was included with the event: Process '5744' failed to start. Port = 25608, Error Code = '-2147023265'. </pre> <br /> Error Code인 -2147023265 값은 0x8007065F이며, 의미하는 바는 "The Windows Installer service failed to start. Contact your support personnel."입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그런데 <a target='tab' href='http://www.sysnet.pe.kr/2/0/11434'>지난번 예제로 만들었던 소켓 서버</a>는 잘 동작했는데 왜 Owin 서버는 문제가 발생하는 걸까요? 그 차이점을 알기 위해 netstat -ano 명령어로 살펴봤습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 소켓 서버에서 29501 포트로 대기한 경우, C:\temp> netstat -ano | findstr 29501 Proto Local Address Foreign Address State PID TCP 127.0.0.1:29501 0.0.0.0:0 LISTENING <span style='color: blue; font-weight: bold'>4928</span> </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // Owin 서버에서 29501 포트로 대기한 경우, C:\temp> netstat -ano | findstr 29501 Proto Local Address Foreign Address State PID TCP 127.0.0.1:29501 0.0.0.0:0 LISTENING <span style='color: blue; font-weight: bold'>4</span> </pre> <br /> 차이점이 보이시나요? 동작을 제대로 한 소켓 서버의 소유권은 해당 프로세스가 소유한 반면, 정상적이지 못했던 Owin 서버는 소켓 소유권이 4번 프로세스(System)에 있습니다. 그러고 보니 System 프로세스가 소켓 소유권을 가지는 상황을 이전에 겪은 적이 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > IIS의 80 포트를 공유하는 응용 프로그램 만드는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1555'>http://www.sysnet.pe.kr/2/0/1555</a> </pre> <br /> 정말 저것 때문에 그런 것인지 간단하게 HttpListener를 이용한 예제를 만들어,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; using System.Net; using System.Text; using System.Threading; namespace ConsoleApp1 { class Program { static int Main(string[] args) { StartHTTP(); return 0; } private static void StartHTTP() { int port = GetPort(); HttpListener httpServer = new HttpListener(); httpServer.Prefixes.Add($"http://localhost:{port}/"); httpServer.AuthenticationSchemes = AuthenticationSchemes.Anonymous; httpServer.Start(); httpServer.BeginGetContext(ProcessRequest, httpServer); Thread.Sleep(-1); } static void ProcessRequest(IAsyncResult ar) { HttpListener listener = ar.AsyncState as HttpListener; HttpListenerContext ctx = listener.EndGetContext(ar); HttpListenerRequest req = ctx.Request; HttpListenerResponse resp = ctx.Response; StringBuilder sb = new StringBuilder(); sb.Append("<html><body><h1>" + DateTime.Now + "</h1>"); sb.Append("</body></html>"); byte[] buf = Encoding.UTF8.GetBytes(sb.ToString()); resp.OutputStream.Write(buf, 0, buf.Length); resp.OutputStream.Close(); listener.BeginGetContext(ProcessRequest, listener); } private static int GetPort() { int port = 29501; string value = Environment.GetEnvironmentVariable("HTTP_PLATFORM_PORT"); if (int.TryParse(value, out int userPort) == true) { port = userPort; } return port; } } } </pre> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1221&boardid=331301885'>위의 코드는 첨부 파일에 포함되어 있습니다.</a>)<br /> <br /> <a target='tab' href='http://www.sysnet.pe.kr/2/0/11434'>지난번 글</a>에서와 같이 테스트를 할 수 있습니다. 위의 예제 코드로 HttpPlatformHandler를 연결하면 Owin 서버와 마찬가지로 HTTP Error 502.3 - Bad Gateway 오류가 발생합니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 실제로 Owin 서버는 내부적으로 HttpListener를 사용합니다. 그렇다면 Owin 서버를 HttpPlatformHandler와 연결하기 위해서는 HttpListener를 Socket으로 교체를 해야 합니다. 다행히 ^^ 찾아보면 이에 대한 작업을 github에서 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Bobris/Nowin ; <a target='tab' href='https://github.com/Bobris/Nowin'>https://github.com/Bobris/Nowin</a> </pre> <br /> 그래서 다음과 같이 Owin 서버를 만들게 되면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>// Install-Package Nowin -Version 0.26.0</span> // <a target='tab' href='https://www.nuget.org/packages/Nowin/'>https://www.nuget.org/packages/Nowin/</a> static class Program { static void Main(string[] args) { int port = GetPort(); string baseAddress = $"http://127.0.0.1:{port}/"; var options = new StartOptions(baseAddress) { <span style='color: blue; font-weight: bold'>ServerFactory = "Nowin",</span> }; using (WebApp.Start<Startup>(options)) { Thread.Sleep(-1); } } private static int GetPort() { int port = 29501; string value = Environment.GetEnvironmentVariable("HTTP_PLATFORM_PORT"); if (int.TryParse(value, out int userPort) == true) { port = userPort; } return port; } } </pre> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1222&boardid=331301885'>위의 코드는 첨부 파일에 포함되어 있습니다.</a>)<br /> <br /> 정상적으로 HttpPlatformHandler와 연동이 되는 것을 확인할 수 있습니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2296
(왼쪽의 숫자를 입력해야 합니다.)