Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-5505

No Message Returned to Client and/or Undertow Premature Close

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Do
    • Icon: Major Major
    • 10.0.0.CR4
    • 10.0.0.CR2
    • Application Client, EE
    • None
    • Hide
      Misunderstanding on this functionality. Client simply exits too early.
      Kindly ignore.
      Thanks for your help Stuart!
      Show
      Misunderstanding on this functionality. Client simply exits too early. Kindly ignore. Thanks for your help Stuart!

      What is your JBoss Version?
      WildFly-10.0.0.CR2

      Have you tried the latest and greatest?
      I believe WildFly-10.0.0.CR2 is the latest but have not tried to build from source

      What version of Java are you using?
      JDK 1.8.0_60-b27

      Have you tried the latest JVM or a different vendor?
      Dropped back to JDK 7 but same issue

      What Operating System are you using?
      Ubuntu 15.04 (fully up to date via apt-get)

      Do you have the correct patches to run the virtual machine?
      No

      Do you have a known OS issue?
      No

      What database/thirdparty jars are you using?
      In the gradle build of my Java SE client app which has 2 Classes my compile dependencies are:
      compile 'io.undertow:undertow-websockets-jsr:1.3.0.CR1' // Pretty sure only one required for Undertow @ClientEndpoint

      Have you asked the thirdparty for help?
      Have had a little back and forth on the undertow-dev list with Stuart Douglas <sdouglas@redhat.com>
      BTW, Stuart seems like a great guy! If there is a communication problem I'm sure it's my fault for not describing the issue correctly.
      I'm going to try to make this the best report I can.

      What configuration changes did you make to JBoss?
      Nothing related to Undertow.
      Changed logging from INFO to ALL.
      Added some security domain stuff for my app but the paths for the websockets I'm testing (just an echo) is outside (not blocked or cut off) by the security-constraint directive in my web.xml

      Does it work if you don't make those changes?
      Same problem with plain jane install

      Why did you make that change?
      Hoping to get some more informative logging.

      Where did you get the information about that change?
      Just plain old logging change not applicable to my issue.

      What is your problem?

      In short... The SERVER seems to think the Websocket CLIENT is closed even before I call .close() on the CLIENT. The CLIENT seems to think it is still open.

      On the CLIENT side I create a new instance of my decorated @ClientEndpoint

      I call a method that contains the call webSocketSession.getBasicRemote().sendText(string);
      The server issues a stack trace similar to:
      2015-10-08 16:15:09 ERROR stderr - java.io.IOException: Connection reset by peer
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.IOUtil.read(IOUtil.java:192)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.NioSocketConduit.read(NioSocketConduit.java:282)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.conduits.IdleTimeoutConduit.read(IdleTimeoutConduit.java:202)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.conduits.ConduitStreamSourceChannel.read(ConduitStreamSourceChannel.java:127)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel.receive(AbstractFramedChannel.java:334)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:38)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:33)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:852)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:835)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)
      2015-10-08 16:15:09 INFO stdout - ServerSide >>> Session M6xvx2ykojsiWaZSJyRVto4l7MQoUpZ4zqSU8T7C closed because of CloseReason[1006]

      No message comes back to the client and in this scenario I am NOT calling .close() in any way.

      However, whenever I add any kind of Thread.sleep() after getBasicRemote().sendText(myString)...

      webSocketSession.getBasicRemote().sendText(myString);
      Thread.sleep(250); // 250 or higher

      The server reports a CloseReason[1006] but there is NO stack trace and I DO get a message back from the server.
      It's as if the the Thread.sleep() is keeping the CLIENT (or the SERVER??) open just long enough to get a response from the server.

      But, in either of these first two cases the CLIENT webSocketSession.isOpen() reports TRUE (stack trace with CloseReason[1006] or no stack trace and CloseReason[1006] on the server) on the client without the .close() method being called on the client.

      Finally, (in a third scenario) when I do call webSocketSession.close() after webSocketSession.sendText(myString); AND Thread.sleep(250); I get a CloseReason[1000] as expected. And, I get my message/echo returned from the server.
      Without Thread.sleep(250); no message is returned from the server.

      Could you hope to answer the question from the information you post?

      Tried several different possible work arounds but no luck using Undertow (very basic decorated POJO) from Java SE to communicate with Wildfly with out the cludge of adding Thread.sleep(250); in my client POJO after webSocketSession.sendText(myString);
      Again, this is just an echo.

      Did you ask a colleague about the problem first? This can save a lot of embarrassment and wasted time.
      Less worried about embarrassment then getting on the right track. That being said I really hope I'm not missing something obvious here.
      Yes, my colleague used a different library on an Android device 'org.java-websocket:Java-WebSocket:1.3.0' and doesn't seem to have this issue.
      I very much want to get this working using Undertow as my final application will have a Java SE part, Android part and Wildfly in the center of it all.

      What error message do you see?
      No errors on the client side – but do NOT get a message when just webSocketSession.getBasicRemote().sendText(string);
      Errors on the server side:
      2015-10-08 16:15:09 ERROR stderr - java.io.IOException: Connection reset by peer
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.IOUtil.read(IOUtil.java:192)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.NioSocketConduit.read(NioSocketConduit.java:282)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.conduits.IdleTimeoutConduit.read(IdleTimeoutConduit.java:202)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.conduits.ConduitStreamSourceChannel.read(ConduitStreamSourceChannel.java:127)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel.receive(AbstractFramedChannel.java:334)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:38)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:33)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:852)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:835)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)
      2015-10-08 16:15:09 INFO stdout - ServerSide >>> Session M6xvx2ykojsiWaZSJyRVto4l7MQoUpZ4zqSU8T7C closed because of CloseReason[1006]

      No errors on the client side – but DO get a message when just webSocketSession.getBasicRemote().sendText(string); Thread.sleep(250);
      Errors on the server side (close code really): CloseReason[1006]

      No errors on the client side – but DO get a message when just webSocketSession.getBasicRemote().sendText(string); Thread.sleep(250);
      No errors on the server side (close code really): CloseReason[1000] – as expected when I call webSocketSession.close(); myself

      No errors on the client side – but do NOT get a message when just webSocketSession.getBasicRemote().sendText(string);
      No errors on the server side (close code really): CloseReason[1000] – as expected when I call webSocketSession.close(); myself

      Post the full stacktrace.

      2015-10-08 16:15:09 ERROR stderr - java.io.IOException: Connection reset by peer
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.IOUtil.read(IOUtil.java:192)
      2015-10-08 16:15:09 ERROR stderr - at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.NioSocketConduit.read(NioSocketConduit.java:282)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.conduits.IdleTimeoutConduit.read(IdleTimeoutConduit.java:202)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.conduits.ConduitStreamSourceChannel.read(ConduitStreamSourceChannel.java:127)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel.receive(AbstractFramedChannel.java:334)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:38)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:33)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:852)
      2015-10-08 16:15:09 ERROR stderr - at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:835)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:88)
      2015-10-08 16:15:09 ERROR stderr - at org.xnio.nio.WorkerThread.run(WorkerThread.java:539)
      2015-10-08 16:15:09 INFO stdout - ServerSide >>> Session M6xvx2ykojsiWaZSJyRVto4l7MQoUpZ4zqSU8T7C closed because of CloseReason[1006]

      Is that the first error message?
      Yes.

      Are there any related WARN messages?
      No.

      Have you tried searching for that error message?
      Yes. Google tells me the client reset or there was a network error.
      There is no network error here (I would think) as the Java SE client and Wildfly server are running on the same PC.

      Is it actually a JBoss error message?
      Yes, but I'm still learning how Wildfly is layered/assembled as I'm moving from Glassfish. This stacktrace might be directly from the Undertow subsystem.

      Have you included the deployment descriptors for the application with the problem?
      No. Not sure it will help. As Indicated above a colleague with a different Websocket client can use my @ServerEndpoint with no issues.

      What did you expect to happen?
      When I created a new webSocketSession [webSocketSession = webSocketContainer.connectToServer(this.getClass(), websocketServerURI)] I expected the webSocketSession on BOTH the server and client side to remain open for communication until I called webSocketSession.close(); myself or MaxSessionIdleTimeout and/or MaxIdleTimeout was reached.

      BTW, I did try setting:
      webSocketContainer.setDefaultMaxSessionIdleTimeout(Long.MAX_VALUE);
      webSocketSession.setMaxIdleTimeout(Long.MAX_VALUE);

      Why did you expect that behaviour?
      It seems to be in line with how I read section 2.1.2 on page 6 of JSR 356 – In my case no close notification is in my code and as both the @ClientEndpoint in the regular JVM and @ServerEndpoint in Wildfly are on the same machine there seems a low chance of a fatal (network or otherwise) error terminating the connection.

      How does your application differ from the many examples that work?
      Not sure. It's really just an echo example.
      I have NOT added any MessageHandlers or ServerEndpointConfg* and am just using the standard @ decorations.

      Have you enabled DEBUG or TRACE logging to see what is really happening?
      Yes. Included what I am seeing above.

      Post the log from around the time you have the problem.
      Done. See above.

      What steps did you take to isolate the problem?
      Reorganized the POJO to isolate where/when different websocket object get set instantiated.

      Do you know what configuration option or api calls causes the problem?
      Not sure. I'm guessing a pre-mature close call on the server side. Or, the client is confusing the server into thinking the session is closed when it should not be.

      If you are reporting a "bug", how do you know it is a bug?
      Only because I can reproduce it and it doesn't behave has expected/described above.

      Can you quote chapter and verse from the specification?
      Well, no. But JSR 356 seems to imply I can open a session and that the session will stay open (so I can exchange messages) until I close it or there is a fatal error.

      Do you have a simple test that reproduces the "bug"?
      Sort of. I will add my Server side Class and my Client side Classes to this report.
      Also, this may be related... This issue does not happen when both my "CLIENT" and "SERVER" are run as an Arquillian test INSIDE Wildfly. But, I wouldn't think that having my CLIENT in Java SE on the same machine and having my SERVER in Wildfly would be a violation 2.1.1 of JSR 356 (as I have only once instance of the @ClientEndpoint and one instance of the @ServerEndpoint)

      Did you search to see whether the "bug" is already fixed?
      I looked in the Undertow JIRA and didn't see anything related.

      SERVER CLASS:

      ackage com.alamon.socket;

      import javax.ejb.Stateless;
      import javax.websocket.*;
      import javax.websocket.server.ServerEndpoint;
      import java.util.logging.Logger;

      @Stateless
      @ServerEndpoint("/echoWS")
      public class EchoWS {

      private Logger logger = Logger.getLogger(EchoWS.class.getName());

      @OnOpen
      public void onOpen(Session session)

      { System.out.println(String.format("ServerSide >>> Connected to ... %s ", session.getId())); }

      @OnClose
      public void onClose(Session session, CloseReason closeReason)

      { System.out.println(String.format("ServerSide >>> Session %s closed because of %s", session.getId(), closeReason)); }

      @OnError
      public void onError(Throwable error)

      { error.printStackTrace(); }


      @OnMessage
      public String onMessage(String string, Session session) { System.out.println(String.format("ServerSide >>> got message %s : session: %s ", string, session.getId())); return String.format("Processed: %s", string); }

      }


      CLIENT CLASSES:

      package com.alamon.migrate;

      import com.alamon.socket.client.EchoCWS;
      import java.util.logging.Logger;

      public class Migrate {

      public static void main(String[] args) { Logger logger = Logger.getLogger(Migrate.class.getName()); EchoCWS echoCWS = new EchoCWS(); echoCWS.sendWorkToServer("HELLO WORLD"); echoCWS.status(); // ClientEndpoint reports open true echoCWS.sendWorkToServer("HELLO WORLD AGAIN"); echoCWS.status(); // ClientEndpoint reports open true //echoCWS.tearDown(); // CloseReason[1006] without this line as expected -- CloseReason[1000] with this line as expected }
      }

      package com.alamon.socket.client;

      import com.alamon.constant.ServerSocketURI;
      import javax.websocket.*;
      import java.io.IOException;
      import java.net.URI;
      import java.util.logging.Logger;


      @ClientEndpoint
      public class EchoCWS {

      private Logger logger = null;
      private ServerSocketURI serverSocketURI = new ServerSocketURI();
      private URI websocketServerURI = null;
      private WebSocketContainer webSocketContainer = null;
      private Session webSocketSession = null;


      public EchoCWS() { logger = Logger.getLogger(this.getClass().getName()); }


      private boolean setUp() {
      try { websocketServerURI = serverSocketURI.getEchoWsUri(); // Get Correct URI Development vs Production logger.info("URI: " + websocketServerURI.toString()); webSocketContainer = ContainerProvider.getWebSocketContainer(); // WebSocket Container //webSocketContainer.setDefaultMaxSessionIdleTimeout(Long.MAX_VALUE); webSocketSession = webSocketContainer.connectToServer(this.getClass(), websocketServerURI); // Connect to the Server //webSocketSession.setMaxIdleTimeout(Long.MAX_VALUE); // Expect webSocketSession (on both server and client) to remain open until specifically closed someplace else or some kind of fatal error } catch (DeploymentException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; }

      return true;

      }

      public boolean tearDown() {
      if (webSocketSession != null) {
      if (webSocketSession.isOpen()) {
      try { webSocketSession.close(); } catch (IOException e) { e.printStackTrace(); return false; }
      }
      }
      webSocketSession = null;
      webSocketContainer = null;
      websocketServerURI = null;
      serverSocketURI = null;
      return true;
      }


      @OnOpen
      public void onOpen(Session session) { System.out.println(String.format("ClientSide >>> Connected to ... %s ", session.getId())); }


      @OnClose
      public void onClose(Session session, CloseReason closeReason) { System.out.println(String.format("ClientSide >>> Session %s closed because of %s", session.getId(), closeReason)); }

      @OnError
      public void onError(Throwable error) { error.printStackTrace(); }

      @OnMessage
      public void onMessage(String string, Session session)

      { System.out.println(String.format("ClientSide >>> got message %s : session: %s ", string, session.getId())); }

      public void status()

      { System.out.println("Socket is open: " + webSocketSession.isOpen()); }

      public void sendWorkToServer(String string) {
      System.out.println(this.getClass().getName() + " >>> Enter sendWorkToServer");

      if (webSocketSession == null || !webSocketSession.isOpen())

      { setUp(); }

      try

      { webSocketSession.getBasicRemote().sendText(string); //Thread.sleep(1000); // Get CloseReason[1006] & No Messsage & Stacktrace on Server when NOT uncommented and don't .close() -- Get CloseReason[1006] with NO Message & NO stacktrace when uncommented and don't .close() -- Get CloseReason[1000] & Message & CloseReason[1000] if .close() myself --- But, I don't think I should need this Thread.sleep(); as the webSocketSession should just stay open so I can do all my communication then close it. }

      catch (IOException e)

      { e.printStackTrace(); }

      System.out.println(this.getClass().getName() + " >>> Exit sendWorkToServer");

      }
      }

              sdouglas1@redhat.com Stuart Douglas (Inactive)
              dennis-3 Dennis Gesker (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: