Hi.

I am using Tomcat 8.0.36 with Atmosphere 2.4.5 ( https://github.com/Atmosphere/atmosphere ) to implement WebSockets with fallbacks such as long polling.

I am writing tests using Tomcat JSR356 implementation.

I studied your WebSocket samples and I am using a fake trustore :

ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
        File keyStorePath = new File("path/to/test.keystore");
cec.getUserProperties().put(WsWebSocketContainer.SSL_TRUSTSTORE_PROPERTY, keyStorePath.getAbsolutePath()); cec.getUserProperties().put(WsWebSocketContainer.SSL_TRUSTSTORE_PWD_PROPERTY, "pouetpouet");

or similarly I am setting the WsWebSocketContainer.SSL_CONTEXT_PROPERTY to a passthrough ssl context, accepting all certificates (it's just for tests, it's ok).


My test looks like :

WebSocketContainer container = ContainerProvider.getWebSocketContainer(); RecordingReceivedMessagesSocket socket = new RecordingReceivedMessagesSocket();

        URI echoUri = new URI(getWSTestURI("/ws/delaislimites"));

ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();
        File keyStorePath = new File("path/to/test.keystore");
cec.getUserProperties().put(WsWebSocketContainer.SSL_TRUSTSTORE_PROPERTY, keyStorePath.getAbsolutePath()); cec.getUserProperties().put(WsWebSocketContainer.SSL_TRUSTSTORE_PWD_PROPERTY, "pouetpouet");

Session wsSession = container.connectToServer(socket, cec, echoUri);

        socket.close();
        log.info("Attente de la fermeture de la socket");
        Assert.assertTrue(socket.awaitClose(10,TimeUnit.SECONDS));
        log.info("La socket doit avoir reçu OK");
Assert.assertTrue(socket.getReceivedMessages().contains("OK"));
        Assert.assertTrue(true);

RecordingReceivedMessagesSocket class looks like :


@ClientEndpoint
@Log4j2
@Getter
public class RecordingReceivedMessagesSocket extends BaseTestSocket
{
    List<String> receivedMessages = new ArrayList<>();

    @OnMessage
    public String onMessage(String msg, Session session)
    {
        log.info("Message reçu : {}", msg);
        this.receivedMessages.add(msg);
        return msg;
    }
}

@ClientEndpoint
@Log4j2
@Getter
public class BaseTestSocket extends Endpoint
{
    private Session session;

    private final CountDownLatch closeLatch;

    public BaseTestSocket()
    {
        this.closeLatch = new CountDownLatch(1);
    }

    @OnOpen
    @Override
    public void onOpen(Session session, EndpointConfig config)
    {
        log.info("Connexion établie.");
        this.session = session;
    }

public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException
    {
        return this.closeLatch.await(duration,unit);
    }

    @OnClose
    @Override
    public void onClose(Session session, CloseReason reason)
    {
        log.info("Connexion fermée.");
        this.closeLatch.countDown();
    }

    public void write(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

public void writeObject(Object object) throws IOException, EncodeException {
        this.session.getBasicRemote().sendObject(object);
    }

    public void close() throws IOException {
        this.session.close();
    }
}


When I implement getWSTestURI() so that it returns a url for a non encrypted request, such as ws://localhost/8084/ws/delaislimites :

* RecordingReceivedMessagesSocket.onMessage gets called with the immediate server reply ("OK").


The ServerEndPoint looks like :


@Log4j2
@ManagedService(path = "/ws/delaislimites")
public class WSDelaisLimites {
    @Inject
    private BroadcasterFactory factory;

    @Inject
    private AtmosphereResourceFactory resourceFactory;

    @Inject
    private MetaBroadcaster metaBroadcaster;

    @Ready(encoders = {JacksonEncoder.class})
    @DeliverTo(DeliverTo.DELIVER_TO.ALL)
    public String onReady(final AtmosphereResource r) {
        log.info("Browser {} connected.", r.uuid());
        return "OK";
    }

    /**
* Invoked when the client disconnect or when an unexpected closing of the underlying connection happens.
     *
     * @param event
     */
    @Disconnect
    public void onDisconnect(AtmosphereResourceEvent event) {
        if (event.isCancelled()) {
log.info("Browser {} unexpectedly disconnected", event.getResource().uuid());
        } else if (event.isClosedByClient()) {
log.info("Browser {} closed the connection", event.getResource().uuid());
        }
    }

/* ... */
    @Message
    public String onMessage(String message) throws IOException {
        StringBuilder sb = new StringBuilder();
        sb.append("Reçu le message texte ");
        sb.append(message);
        log.info(sb.toString());
        return message;
    }
}

So, I am getting "OK".


When I connect through SSL, with a url like wss://localhost:8765/ws/delaislimites :

* RecordingReceivedMessagesSocket.onMessage never gets called with the "OK" reply.


I tried to add the following block :

        CountDownLatch latch = new CountDownLatch(1);
        BasicText handler = new BasicText(latch);
        wsSession.addMessageHandler(handler);
        socket.write("Pouet");
        Assert.assertTrue(handler.getLatch().await(10, TimeUnit.SECONDS));

between

Session wsSession = container.connectToServer(socket, cec, echoUri);

and

        socket.close();

to check that some other stuff works (like in your tests).

As expected, it does, and the BasicText handler gets a reply from the server.

However, it does not get the initial reply too (and it seems quite normal to me as it is added too late).

If I only add a

        socket.write("Pouet");

RecordingReceivedMessagesSocket.onMessage is also called with server messages.

So, is this difference in behaviour to be expected ? Is there some point in spec that I missed that commands it ?

Thanks in advance for your explanations.

Ludovic


|
| AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT.
|


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to