Program Tip

자동으로 연결을 닫는 websocket

programtip 2020. 11. 15. 11:39
반응형

자동으로 연결을 닫는 websocket


부두를 기반으로 웹 소켓 서버가 내장 된 Java로 응용 프로그램을 만들고 있습니다. 클라이언트는 Google 크롬의 기본 웹 소켓 구현입니다. 연결이 종료 된 후 서버와 클라이언트간에 전송이없는 경우에만 모든 것이 정상적으로 작동합니다. 누가 연결을 종료하는지 잘 모르겠습니다 : 부두 서버 또는 크롬 브라우저.

이에 대한 해결책은 x 초마다 메시지를 보내는 것이지만, 더 나은 해결책이 열려 있습니다.

그래서 ... 제 질문은 다음과 같습니다.

  1. 이것이 웹 소켓 프로토콜에 필요한 것입니까?이 경우 크롬 브라우저가 연결을 닫습니까?

  2. 이것은 더 많은 부두와 관련이 있고 웹 소켓 프로토콜과 다소 관련이 있습니까? 이 경우 부두에서 어떻게 비활성화합니까?

  3. 또 다른 문제가 있습니까 ??

감사

업데이트 : 초당 1 개의 메시지를 보내더라도 여전히 연결이 닫힙니다.


세 번째 질문에 대한 답변 : 클라이언트는 어쨌든 일시적인 네트워크 문제에 대처할 수 있기를 원합니다. 예를 들어, 사용자가 최대 절전 모드로 전환되는 회의 사이에 랩톱을 닫거나 네트워크가 일시적으로 중단된다고 가정 해 보겠습니다.

해결책은 onclose웹 소켓 클라이언트 에서 이벤트 를 수신하고 이벤트가 발생하면 클라이언트 측 시간 제한을 설정하여 연결을 다시 여는 것입니다.

function setupWebSocket(){
    this.ws = new WebSocket('wss://host:port/path');
    this.ws.onerror = ...;
    this.ws.onopen = ...;
    this.ws.onmessage = ...;
    this.ws.onclose = function(){
        setTimeout(setupWebSocket, 1000);
    };
}

때때로 핑 메시지를 보내야합니다. 기본 시간 제한은 300 초라고 생각합니다. 브라우저에서 웹 소켓 핑 / 퐁 프레임 보내기


나는 다소 빠르고 더러운 또 다른 해결책을 찾았습니다. 저수준 접근 방식을 사용하여 WebSocket을 구현하고 onOpen메서드를 직접 구현하면 WebSocket.Connection인터페이스를 구현하는 개체를 받게 됩니다. 이 개체에는 조정할 수 있는 setMaxIdleTime 메서드가 있습니다.


실제로 WebSocketServletFactory인스턴스를 사용하여 Jetty 서버 측 구성에서 시간 제한 간격을 설정할 수 있습니다 . 예를 들면 :

WebSocketHandler wsHandler = new WebSocketHandler() {
    @Override
    public void configure(WebSocketServletFactory factory) {
        factory.getPolicy().setIdleTimeout(1500);
        factory.register(MyWebSocketAdapter.class);
        ...
    }
}

방금 이것에 대한 해결책을 찾았습니다. 설정하려는 것은 WebSocketServlet의 maxIdleTime (밀리 초)입니다. 이를 수행하는 방법은 서블릿을 구성하는 방법에 따라 다릅니다. Guice ServletModule을 사용하면 10 시간의 제한 시간 동안 다음과 같이 할 수 있습니다.

serve("ws").with(MyWSServlet.class, 
new HashMap<String, Sring>(){{ put("maxIdleTime", TimeUnit.HOURS.toMillis(10) + ""); }});

0보다 작은 것은 내가 믿는 무한 유휴 시간입니다.


나는 이것이 부두 문제라고 생각합니다. 비활성으로 인해 WebSocket 연결을 닫는 브라우저를 보지 못했고 WebSocket 연결 시간을 초과하는 다른 WebSocket 서버도 발견하지 못했습니다.

Jetty는 주로 HTTP 기반 애플리케이션 서블릿을 구축하는 데 중점을 둡니다. 이러한 맥락에서 HTTP 연결은 매우 적극적으로 정리해야하며 HTTP는 수명이 긴 연결 용으로 설계되지 않았으므로 짧은 기본 시간 제한을 갖는 것이 합리적입니다.

설명하신 정확한 문제 (활동으로도 닫힘)를 보지 못했지만 30 초 동안 활동이 없으면 WebSocket 연결이 닫히는 것을 확인했습니다. 이전 버전의 Jetty 또는 다른 이유로 현재 버전에서는 타이머가 WebSocket 활동에 의해 재설정되지 않을 수 있습니다. BlockingChannelConnector 개체에서 setMaxIdleTime 메서드를 사용하여 시간 제한 값을 Integer MAX_VALUE로 설정하여이 문제를 해결합니다.


이 시간 초과는 실제로 TCP / IP의 일부이며 해결책은 가끔 빈 메시지를 보내는 것입니다.


다음은 WebSocketServlet을 사용하여 Jetty의 websocket 시간 제한 (가장 가능성이 높은 원인)을 구성하는 방법에 대한 예입니다 (스칼라에서는 죄송하지만 구문은 거의 동일합니다).

import javax.servlet.annotation.WebServlet
import org.eclipse.jetty.websocket.servlet.{WebSocketServletFactory, WebSocketServlet}

@WebServlet(name = "WebSocket Servlet")
class WebsocketServlet extends WebSocketServlet {
  override def configure(factory: WebSocketServletFactory): Unit = {
    factory.getPolicy.setIdleTimeout(1000 * 3600)
    factory.register(classOf[ClientWebsocket])
  }
}

I have a similar experience and I believe that it might be the browser that is cutting the session short. I also set the maxIdleTimeout, but the session is dropped regardless. To me, it looks like it is the client (the browser) that is timing out the session and then hangs up.

Don't know how to work around it.


Same issue: Was using WebSockets & sockjs-client/1.0.3/sockjs library with @ServerEndPoint on Java Server side. The websocket connections kept breaking variably.

I moved to using Stomp and sockJS (abandoning the @ServerEndpoint) but encountered another issue popular on SO - /info=34424 - with 404 error -

I had to abandon using the xml approach of Stomp Spring library as suggested at other places. I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldung worked(for me without changing from Spring 4.2 to 5).

After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>

참고URL : https://stackoverflow.com/questions/9056159/websocket-closing-connection-automatically

반응형