On 18/07/2016 16:25, l.pe...@senat.fr wrote:
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);
I realised that my message was incomplete and, by the way, found the
answer myself.
When I do not go SSL, I do not call the same version of connectToServer.
I am doing
Session wsSession = container.connectToServer(socket, echoUri);
This version os connectToServer gets an Object rather than a endpoint as
first parameter and, among other things, looks for the ClientEndpoint
annotation.
If it finds it, it wraps it in a PojoEndpointClient (pojo is the first
parameter of connectToServer) :
Endpoint ep = new PojoEndpointClient(pojo,
Arrays.asList(annotation.decoders()));
So, if I do
container.connectToServer(new PojoEndpointClient(socket, new
ArrayList<>()), cec, echoUri);
everything is fine, because of the inits that PojoEndpointClient does.
Sorry for the noise.
Ludovic
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