tyrus
  1. tyrus
  2. TYRUS-192

ServerEndpoint creates Session on #2 after #1 attempt got forced close()

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 1.0
    • Fix Version/s: 1.1
    • Component/s: None
    • Labels:
      None

      Description

      On @OnOpen, I added some logic to close the Session.

      On Javascript, after the first attempt, I see websocket.readyState === 3 (closed).
      On second attempt, Tyrus opens the session and gives me a readyState === 1 (open).

      Problem is: the second attempt did not go through @OnOpen

        Issue Links

          Activity

          Hide
          Pavel Bucek added a comment -

          Hi Bruno,

          can you please share more details about your testcase?

          Show
          Pavel Bucek added a comment - Hi Bruno, can you please share more details about your testcase?
          Hide
          Pavel Bucek added a comment -

          btw, it is most likely related to TYRUS-172 and TYRUS-176 .. it would be really great if you could provide reproducible testcase.

          Show
          Pavel Bucek added a comment - btw, it is most likely related to TYRUS-172 and TYRUS-176 .. it would be really great if you could provide reproducible testcase.
          Hide
          Bruno Borges added a comment -

          I can only reproduce this on a large project.

          Still working on a sample app... Please hold

          Show
          Bruno Borges added a comment - I can only reproduce this on a large project. Still working on a sample app... Please hold
          Hide
          Bruno Borges added a comment -

          This is the reproducable code:

          SampleWebSocket.java:

           
          @ServerEndpoint(value = "/ws", configurator = SampleConfigurator.class)
          public class SampleWebSocket {
          
              @OnOpen
              public void onOpen(Session session, EndpointConfig config) {
                  try {
                      System.out.println("Called @OnOpen");
                      session.close();
                  } catch (IOException ex) {
                      Logger.getLogger(SampleWebSocket.class.getName()).log(Level.SEVERE, null, ex);
                  }
              }
          }
          

          SampleConfigurator.java

           
          public class SampleConfigurator extends ServerEndpointConfig.Configurator {
          
              @Override
              public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
                  super.modifyHandshake(sec, request, response); //To change body of generated methods, choose Tools | Templates.
              }
              
          }
          

          index.jsp

           
          <script>
          var _ws = new WebSocket("ws://localhost:8080/bug-tyrus-192/ws");
          _ws.onopen = function() {alert("opened: "+_ws.readyState);}
          </script>
          

          The readyState always shows as "1" in this example, which should not happen because the connection is being closed inside onOpen, and at the second and consecutive calls, onOpen is not called anymore. (press F5 reloading the page).

          Show
          Bruno Borges added a comment - This is the reproducable code: SampleWebSocket.java: @ServerEndpoint(value = "/ws", configurator = SampleConfigurator.class) public class SampleWebSocket { @OnOpen public void onOpen(Session session, EndpointConfig config) { try { System.out.println("Called @OnOpen"); session.close(); } catch (IOException ex) { Logger.getLogger(SampleWebSocket.class.getName()).log(Level.SEVERE, null, ex); } } } SampleConfigurator.java public class SampleConfigurator extends ServerEndpointConfig.Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { super.modifyHandshake(sec, request, response); //To change body of generated methods, choose Tools | Templates. } } index.jsp <script> var _ws = new WebSocket("ws://localhost:8080/bug-tyrus-192/ws"); _ws.onopen = function() {alert("opened: "+_ws.readyState);} </script> The readyState always shows as "1" in this example, which should not happen because the connection is being closed inside onOpen , and at the second and consecutive calls, onOpen is not called anymore. (press F5 reloading the page).
          Hide
          Bruno Borges added a comment -

          Pavel, this issue is Critical, could you please change the level?

          There's no way to workaround this.

          Show
          Bruno Borges added a comment - Pavel, this issue is Critical, could you please change the level? There's no way to workaround this.
          Hide
          Bruno Borges added a comment -

          Extra: after I try some requests, GlassFish stops responding all types of requests (servlet, jsp, etc) over the application containing this WebSocket.

          Show
          Bruno Borges added a comment - Extra: after I try some requests, GlassFish stops responding all types of requests (servlet, jsp, etc) over the application containing this WebSocket.
          Hide
          Bruno Borges added a comment -

          Confirmed: GlassFish stops responding to any application, except Admin Console. Don't know if only blocks applications containing WebSockets though.

          Show
          Bruno Borges added a comment - Confirmed: GlassFish stops responding to any application, except Admin Console. Don't know if only blocks applications containing WebSockets though.
          Hide
          Pavel Bucek added a comment -

          thanks for detailed info! sample app would be great (you can send me an email directly to pavel.bucek at oracle.com), but I guess I can re-create it from code snippets you've shared.

          There is still some info I would like to know:

          • container version/tyrus version
          • browser version
          • os (win/linux/mac os x), jdk version

          I can change the level, but it is more like our internal priority and I don't see this (yet) as a release stopper (which corresponds to "Critical"). Not saying we won't spend time on this, just we might have some other higher priority tasks in our queue.

          Show
          Pavel Bucek added a comment - thanks for detailed info! sample app would be great (you can send me an email directly to pavel.bucek at oracle.com), but I guess I can re-create it from code snippets you've shared. There is still some info I would like to know: container version/tyrus version browser version os (win/linux/mac os x), jdk version I can change the level, but it is more like our internal priority and I don't see this (yet) as a release stopper (which corresponds to "Critical"). Not saying we won't spend time on this, just we might have some other higher priority tasks in our queue.
          Hide
          Bruno Borges added a comment -

          Reason I think this is critical is that my logic is related to accessing HttpSession at the modifyHandshake, to get user data from there and only create the WS session if the logic is ready. If I can't work at consecutive attempts and intercept onOpen, then I can't let my users connect to this WS Endpoint. This might also affect secured WebSocket sessions based on User Principal.

          • Container: GF 4.0 final
          • Browser: Chrome latest version
          • Environment: Linux + Oracle JDK 7u21
          Show
          Bruno Borges added a comment - Reason I think this is critical is that my logic is related to accessing HttpSession at the modifyHandshake, to get user data from there and only create the WS session if the logic is ready. If I can't work at consecutive attempts and intercept onOpen, then I can't let my users connect to this WS Endpoint. This might also affect secured WebSocket sessions based on User Principal. Container: GF 4.0 final Browser: Chrome latest version Environment: Linux + Oracle JDK 7u21
          Hide
          Bruno Borges added a comment -

          Found out that bug only happens if I call session.close() inside @OnOpen

          Show
          Bruno Borges added a comment - Found out that bug only happens if I call session.close() inside @OnOpen
          Hide
          Pavel Bucek added a comment -

          reproduced the issue, glassfish stops responding after ~3 initial requests.

          I have fix ready in my local workspace, should be out today. With this fix, same scenario will do for each request:

          1) call server-side onOpen (session.close() call is here)
          2a) client-side javascript invokes ws.onopen with readystate 1
          2b) server-side sends closing frame
          3) client-side javascript invokes ws.onclose with readystate 3

          I guess 2a and 2b do not depend on each other, so order of these invocations might be changed sometimes, thus ws.readystate could be 3 during onopen sometimes.. anyway, onclose should be always called.

          Show
          Pavel Bucek added a comment - reproduced the issue, glassfish stops responding after ~3 initial requests. I have fix ready in my local workspace, should be out today. With this fix, same scenario will do for each request: 1) call server-side onOpen (session.close() call is here) 2a) client-side javascript invokes ws.onopen with readystate 1 2b) server-side sends closing frame 3) client-side javascript invokes ws.onclose with readystate 3 I guess 2a and 2b do not depend on each other, so order of these invocations might be changed sometimes, thus ws.readystate could be 3 during onopen sometimes.. anyway, onclose should be always called.
          Hide
          Pavel Bucek added a comment -

          fixed in the trunk (rev 670)

          Show
          Pavel Bucek added a comment - fixed in the trunk (rev 670)

            People

            • Assignee:
              Pavel Bucek
              Reporter:
              Bruno Borges
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: