Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
(연관된 글이 3개 있습니다.)

사용자 정의 웹 서버(EXE)를 IIS에서 호스팅하는 방법 - HttpPlatformHandler (Reverse Proxy)

IIS 서버를 Reverse Proxy 서버로 사용할 수 있도록 해주는 구성 요소가 바로 HttpPlatformHandler입니다. 동작 방식은 다음과 같이 간단합니다.

http_platform_handler_1.png

사용법도 간단합니다. HttpPlatformHandler를 IIS 웹 서버에 설치 후,

HttpPlatformHandler v1.2
; https://www.iis.net/downloads/microsoft/httpplatformhandler
; https://learn.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference

여러분들의 EXE 응용 프로그램이 배포되는 폴더를 웹 사이트의 루트 디렉터리로 지정한 후, 다음과 같은 내용을 포함한 web.config 파일을 만들어 주면 됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
    </handlers>
    <httpPlatform processPath="d:\temp\ConsoleApp1.exe" 
                  arguments="" 
                  stdoutLogEnabled="false" stdoutLogFile="C:\temp\LogFiles\test.log">
    </httpPlatform>
  </system.webServer>
</configuration>

이후 IIS는 웹 사이트의 설정된 포트(예를 들어, 8094)로 요청이 들어오면 이를 w3wp.exe의 web.config 설정에 따라 여러분들의 웹 서버(이 글에서는 ConsoleApp1.exe)로 전달하는 중계 역할을 합니다. 참고로, 이때 만약 최초 요청이라면 웹 서버(ConsoleApp1.exe) 프로세스를 하나 새로 생성해주는 역할까지 합니다.

그런데 여기서 재미있는 점이 있습니다. IIS는 웹 가든 같은 설정에 따라 w3wp.exe를 다중으로 띄울 수 있고 이에 따라 웹 서버(ConsoleApp1.exe)도 다중으로 뜨는 식의 구성이 가능합니다. 문제는 이때 웹 서버(ConsoleApp1.exe)가 어떤 포트로 소켓을 열고 있어야 하느냐입니다. HttpPlatformHandler는 이를 위해 임의의 포트 번호를 환경 변수(HTTP_PLATFORM_PORT)를 통해 자식 프로세스에 전달하는데, 따라서 자식 프로세스는 이 환경 변수(HTTP_PLATFORM_PORT)를 인식하고 자신의 서버 소켓이 열고 있어야 할 포트로 지정할 수 있어야 합니다.

간단한 예를 들기 위해 ConsoleApp1.exe 실행 파일을 다음과 같은 코드로 만들 수 있습니다.

using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static int Main(string[] args)
        {
            SocketWait(GetPort());
            return 0;
        }

        private static void SocketWait(int port)
        {
            TcpListener tl = new TcpListener(IPAddress.Loopback, port);
            tl.Start(5);

            while (true)
            {
                Socket socket = tl.AcceptSocket();

                byte[] buf = new byte[4096];
                socket.Receive(buf);

                string text = $"<html><head><title></title></head><body>TIME : {DateTime.Now}</body></html>";
                string output = $"HTTP/1.1 200 OK\r\nCache-Control : no-cache, private\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length : {text.Length}\r\nDate : Mon, 24 Nov 2014 12:03:43 GMT\r\n\r\n";
                buf = Encoding.UTF8.GetBytes(output + text);
                socket.Send(buf);

                socket.Close();
            }
        }

        private static int GetPort()
        {
            int port = 29501;

            string value = Environment.GetEnvironmentVariable("HTTP_PLATFORM_PORT");

            if (int.TryParse(value, out int userPort) == true)
            {
                port = userPort;
            }

            Log($"PORT = {port}");

            return port;
        }

        public static void Log(string msg)
        {
            Console.WriteLine(Process.GetCurrentProcess().Id + ": " + msg);
            Console.Out.Flush();
        }
    }
}

(첨부 파일은 이 글의 예제 코드를 포함합니다.)

간단하죠? ^^ 실제로 위의 ConsoleApp1.exe를 HttpPlatformHandler에 지정해 웹 브라우저로 요청을 보내면 w3wp.exe의 자식 프로세스로 ConsoleApp1.exe가 실행되고 응답을 웹 브라우저로 전송하는 것을 확인할 수 있습니다.




헌데 HTTP_PLATFORM_PORT 환경 변수값을 인식하는 기존 웹 서버들이 얼마나 있겠냐고 생각할 수 있는데요, 다행히 HttpPlatformHandler는 자식 프로세스에서 임의의 환경 변수를 설정해서 넘겨주는 것도 가능합니다. 자세한 설명은 아래의 문서에서,

HttpPlatformHandler Configuration Reference
; https://learn.microsoft.com/en-us/iis/extensions/httpplatformhandler/httpplatformhandler-configuration-reference

Understanding IIS HTTPPlatformHandler using Tomcat 8
; https://learn.microsoft.com/en-us/archive/blogs/manjug/understanding-iis-httpplatformhandler-using-tomcat-8

Tomcat, Jetty 등의 웹 서버를 HttpPlatformHandler를 이용해 IIS의 호스팅 서비스를 받는 방법을 보면 됩니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 2/24/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  10  11  [12]  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13329정성태4/24/20233706Windows: 246. Win32 C/C++ - 직접 띄운 대화창 템플릿을 위한 Modal 메시지 루프 생성파일 다운로드1
13328정성태4/19/20233379VS.NET IDE: 184. Visual Studio - Fine Code Coverage에서 동작하지 않는 Fake/Shim 테스트
13327정성태4/19/20233794VS.NET IDE: 183. C# - .NET Core/5+ 환경에서 Fakes를 이용한 단위 테스트 방법
13326정성태4/18/20235205.NET Framework: 2109. C# - 닷넷 응용 프로그램에서 SQLite 사용 (System.Data.SQLite) [1]파일 다운로드1
13325정성태4/18/20234505스크립트: 48. 파이썬 - PostgreSQL의 with 문을 사용한 경우 연결 개체 누수
13324정성태4/17/20234319.NET Framework: 2108. C# - Octave의 "save -binary ..."로 생성한 바이너리 파일 분석파일 다운로드1
13323정성태4/16/20234260개발 환경 구성: 677. Octave에서 Excel read/write를 위한 io 패키지 설치
13322정성태4/15/20235038VS.NET IDE: 182. Visual Studio - 32비트로만 빌드된 ActiveX와 작업해야 한다면?
13321정성태4/14/20233827개발 환경 구성: 676. WSL/Linux Octave - Python 스크립트 연동
13320정성태4/13/20233805개발 환경 구성: 675. Windows Octave 8.1.0 - Python 스크립트 연동
13319정성태4/12/20234291개발 환경 구성: 674. WSL 2 환경에서 GNU Octave 설치
13318정성태4/11/20234114개발 환경 구성: 673. JetBrains IDE에서 "Squash Commits..." 메뉴가 비활성화된 경우
13317정성태4/11/20234227오류 유형: 855. WSL 2 Ubuntu 20.04 - error: cannot communicate with server: Post http://localhost/v2/snaps/...
13316정성태4/10/20233553오류 유형: 854. docker-compose 시 "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)" 오류 발생
13315정성태4/10/20233750Windows: 245. Win32 - 시간 만료를 갖는 컨텍스트 메뉴와 윈도우 메시지의 영역별 정의파일 다운로드1
13314정성태4/9/20233828개발 환경 구성: 672. DosBox를 이용한 Turbo C, Windows 3.1 설치
13313정성태4/9/20233911개발 환경 구성: 671. Hyper-V VM에 Turbo C 2.0 설치 [2]
13312정성태4/8/20233932Windows: 244. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (개선된 버전)파일 다운로드1
13311정성태4/7/20234442C/C++: 163. Visual Studio 2022 - DirectShow 예제 컴파일(WAV Dest)
13310정성태4/6/20234020C/C++: 162. Visual Studio - /NODEFAULTLIB 옵션 설정 후 수동으로 추가해야 할 library
13309정성태4/5/20234206.NET Framework: 2107. .NET 6+ FileStream의 구조 변화
13308정성태4/4/20234097스크립트: 47. 파이썬의 time.time() 실숫값을 GoLang / C#에서 사용하는 방법
13307정성태4/4/20233867.NET Framework: 2106. C# - .NET Core/5+ 환경의 Windows Forms 응용 프로그램에서 HINSTANCE 구하는 방법
13306정성태4/3/20233668Windows: 243. Win32 - 윈도우(cbWndExtra) 및 윈도우 클래스(cbClsExtra) 저장소 사용 방법
13305정성태4/1/20234032Windows: 242. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (쉬운 버전)파일 다운로드1
13304정성태3/31/20234387VS.NET IDE: 181. Visual Studio - C/C++ 프로젝트에 application manifest 적용하는 방법
1  2  3  4  5  6  7  8  9  10  11  [12]  13  14  15  ...