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

비밀번호

댓글 작성자
 




... 16  17  18  19  20  21  22  23  24  25  26  27  28  29  [30]  ...
NoWriterDateCnt.TitleFile(s)
12875정성태12/13/20216488스크립트: 35. python - time.sleep(...) 호출 시 hang이 걸리는 듯한 문제
12874정성태12/13/20216466오류 유형: 773. shell script 실행 시 "$'\r': command not found" 오류
12873정성태12/12/20217586오류 유형: 772. 리눅스 - PATH에 등록했는데도 "command not found"가 나온다면?
12872정성태12/12/20217376개발 환경 구성: 615. GoLang과 Python 빌드가 모두 가능한 docker 이미지 만들기
12871정성태12/12/20217509오류 유형: 771. docker: Error response from daemon: OCI runtime create failed
12870정성태12/9/20216103개발 환경 구성: 614. 파이썬 - PyPI 패키지 만들기 (4) package_data 옵션
12869정성태12/8/20218328개발 환경 구성: 613. git clone 실행 시 fingerprint 묻는 단계를 생략하는 방법
12868정성태12/7/20216891오류 유형: 770. twine 업로드 시 "HTTPError: 400 Bad Request ..." 오류 [1]
12867정성태12/7/20216584개발 환경 구성: 612. 파이썬 - PyPI 패키지 만들기 (3) entry_points 옵션
12866정성태12/7/202113955오류 유형: 769. "docker build ..." 시 "failed to solve with frontend dockerfile.v0: failed to read dockerfile ..." 오류
12865정성태12/6/20216652개발 환경 구성: 611. 파이썬 - PyPI 패키지 만들기 (2) long_description, cmdclass 옵션
12864정성태12/6/20215116Linux: 46. WSL 환경에서 find 명령을 사용해 파일을 찾는 방법
12863정성태12/4/20217029개발 환경 구성: 610. 파이썬 - PyPI 패키지 만들기
12862정성태12/3/20215771오류 유형: 768. Golang - 빌드 시 "cmd/go: unsupported GOOS/GOARCH pair linux /amd64" 오류
12861정성태12/3/20218000개발 환경 구성: 609. 파이썬 - "Windows embeddable package"로 개발 환경 구성하는 방법
12860정성태12/1/20216101오류 유형: 767. SQL Server - 127.0.0.1로 접속하는 경우 "Access is denied"가 발생한다면?
12859정성태12/1/202112278개발 환경 구성: 608. Hyper-V 가상 머신에 Console 모드로 로그인하는 방법
12858정성태11/30/20219528개발 환경 구성: 607. 로컬의 USB 장치를 원격 머신에 제공하는 방법 - usbip-win
12857정성태11/24/20216994개발 환경 구성: 606. WSL Ubuntu 20.04에서 파이썬을 위한 uwsgi 설치 방법
12856정성태11/23/20218795.NET Framework: 1121. C# - 동일한 IP:Port로 바인딩 가능한 서버 소켓 [2]
12855정성태11/13/20216171개발 환경 구성: 605. Azure App Service - Kudu SSH 환경에서 FTP를 이용한 파일 전송
12854정성태11/13/20217722개발 환경 구성: 604. Azure - 윈도우 VM에서 FTP 여는 방법
12853정성태11/10/20216089오류 유형: 766. Azure App Service - JBoss 호스팅 생성 시 "This region has quota of 0 PremiumV3 instances for your subscription. Try selecting different region or SKU."
12851정성태11/1/20217446스크립트: 34. 파이썬 - MySQLdb 기본 예제 코드
12850정성태10/27/20218596오류 유형: 765. 우분투에서 pip install mysqlclient 실행 시 "OSError: mysql_config not found" 오류
12849정성태10/17/20217738스크립트: 33. JavaScript와 C#의 시간 변환 [1]
... 16  17  18  19  20  21  22  23  24  25  26  27  28  29  [30]  ...