카테고리 없음

IIS + Tomcat(spring boot) + WebSocket

백봉 2024. 8. 1. 17:08

지속적으로 데이터를 받아야하는 경우가 있다. 
그러나 클라이언트에서는 딱히 줄 필요는 없다. 

그래서 SSE(Server Side Event)를 이용해서 개발을 했었다. 내장톰캣만으로는 잘 됐었으니까.

그런데 운영환경인 IIS + Tomcat 구조에 적용해보니 모든 이벤트들이 버퍼에 담겼다가 연결이 종료되고 한번에 출력이 됐다. 원하는 시나리오가 아니다. 

이것저것 하다가 마감에 쫒겨 http 폴링으로 마무리 하고 sse 는 잠시 주석을 해뒀었다. 

 

바쁜일들이 많이 지나가고 내부 인테리어를 하는데 SSE 를 소생시켜 다시 써보려고 하니 좀처럼 해결이 되지 않았다. 

한참 찾아보는데, 답이 없다고 생각하며 결론에 도달하던 중 이런 글을 봤다. 

 

그냥 웹소켓으로 하는게 낫겠다. 

 

WEB(IIS) + WAS(Tomcat + springboot) 에서 웹소켓 사용하기

IIS는 항상 찾아보면 별 정보가 많지 않기도 하고, 한국어로 번역이 되어있는것이 오히려 더 헷갈리게 할 때가 많다. 

 

우선 IIS 는 톰캣 커넥터를 이용해서 WAS 랑 붙였었다. 물론 ajp 프로토콜을 사용했는데, 이걸로는 웹소켓을 사용할 수가 없다. 

톰캣 커넥터를 걷어내버리고 리버스 프록시로 사용하기로 한다.

 

 

1. IIS 에 ARR, URL 재작성을 설치

https://www.iis.net/downloads/microsoft/application-request-routing

 

Application Request Routing : The Official Microsoft IIS Site

Overview IIS Application Request Routing (ARR) 3 enables Web server administrators, hosting providers, and Content Delivery Networks (CDNs) to increase Web application scalability and reliability through rule-based routing, client and host name affinity, l

www.iis.net

https://www.iis.net/downloads/microsoft/url-rewrite

 

URL Rewrite : The Official Microsoft IIS Site

Overview IIS URL Rewrite 2.1 enables Web administrators to create powerful rules to implement URLs that are easier for users to remember and easier for search engines to find. By using rule templates, rewrite maps, .NET providers, and other functionality i

www.iis.net

 

2. Windows 기능 추가에서 Websocket을 설치한다.

 

3. 구성 편집기에서 Websocket 을 활성화

 

4. URL 재작성 작성

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <!-- Redirect .jsp requests to Tomcat -->
        <rule name="Redirect JSP" stopProcessing="true">
          <match url=".*\.jsp$" />
          <action type="Rewrite" url="http://localhost:8081/{R:0}" />
        </rule>
        
        <!-- Redirect .do requests to Tomcat -->
        <rule name="Redirect DO" stopProcessing="true">
          <match url=".*\.do$" />
          <action type="Rewrite" url="http://localhost:8081/{R:0}" />
        </rule>
        
        <!-- Redirect /api/* requests to Tomcat -->
        <rule name="Redirect API" stopProcessing="true">
          <match url="^api/(.*)" />
          <action type="Rewrite" url="http://localhost:8081/api/{R:1}" />
                    <serverVariables>
                        <set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="0" />
                    </serverVariables>
        </rule>
        
        <!-- Redirect /open/rest/* requests to Tomcat -->
        <rule name="Redirect Open Rest" stopProcessing="true">
          <match url="^open/rest/(.*)" />
          <action type="Rewrite" url="http://localhost:8081/open/rest/{R:1}" />
        </rule>
        
        <!-- Redirect /ws requests to Tomcat -->
        <rule name="Redirect WebSocket" stopProcessing="true">
          <match url="^ws$" />
          <action type="Rewrite" url="http://localhost:8081/ws" />
          <serverVariables>
              <set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" />
          </serverVariables>
        </rule>
        
        <!-- Redirect /ws/~ requests to Tomcat -->
        <rule name="Redirect WebSocket2" stopProcessing="true">
          <match url="^ws/.*$" />
          <action type="Rewrite" url="http://localhost:8081/{R:0}" />
           <serverVariables>
              <set name="HTTP_SEC_WEBSOCKET_EXTENSIONS" value="" />
          </serverVariables>
        </rule>
        
        <!-- Redirect /ws requests to node -->
        <rule name="Redirect WebSocket to node" stopProcessing="true">
          <match url="^wsnode$" />
          <action type="Rewrite" url="http://localhost:8082/wsnode" />
        </rule>
      </rules>
    </rewrite>
     <urlCompression doDynamicCompression="false"/>
  </system.webServer>
</configuration>

여기까지로 다 됐고, node.js는 여기까지의 설정으로 websocket이 정상 작동한다. 그러나 톰캣, 스프링부트는 안된다. 

 

5. 웹소켓url 재작성에 다시 들어가서 서버 변수 추가

/ws으로 웹소켓을 핸들링 하니 여기에 
HTTP_SEC_WEBSOCKET_EXTENSIONS = 0 추가

 

6. 서버 변수 허용 리스트에 HTTP_SEC_WEBSOCKET_EXTENSIONS 를 추가한다.

 

 

요청과 응답 샘플

Handshake Details

Request URL: http://***
Request Method: GET
Status Code: 101
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: noe5dJU54ydQ3DAolCRqsQ==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: ***
Response Headers
Upgrade: websocket
Set-Cookie: SCOUTER=z53jfncufbfc48; Max-Age=2147483647; Expires=Tue, 19 Aug 2092 11:06:28 GMT; Path=/
Sec-WebSocket-Accept: mg/2sM4gywHETMqAiCZufjziU8Q=
X-Powered-By
0: ARR/3.0
1: ASP.NET
Connection: Upgrade
Date: Thu, 01 Aug 2024 07:52:21 GMT
 

 

주의사항. 

세팅해놓으면 생성되는 web.config는 배포 중 폴더를 통째로 교체하면 같이 삭제될 수 있으니 백업을 잘 해놓는게 좋다. 

 

 

출처:

https://community.home-assistant.io/t/solved-access-via-iis-reverse-proxy-died-after-upgrade-to-0-58/34408

 

[Solved] Access via IIS reverse proxy died after upgrade to 0.58

My remote access died after upgrading to Home Assistant 0.58. I does not pass the loading spinner. I’m using IIS reverse proxy (ARR) with Let’s Encrypt. LAN access still works fine. The regular procedure of cleaning the browser has no effect. Removing

community.home-assistant.io

https://www.oxygenxml.com/doc/versions/26.1.0/ug-waCustom/topics/WA-websocket.html

 

How to Enable WebSocket Support When Using IIS as a Reverse Proxy

To enable WebSocket support in IIS version 8 or later, complete the configuration steps in one of the following methods: Method 1 In the Server Manager, go to the Add Role and Features wizard and select Server Roles. In the Roles pane, under , select WebSo

www.oxygenxml.com

https://adrianjnkns.medium.com/iis-as-reverse-proxy-to-websocket-server-c4fb5a7166f5