// Due to the time it takes for an async request to be scheduled it might actually be the one that returns the
// 'another connection still open' error. Therefore we need to check both.
@Test
	@RunAsClient
	public void simpleSession() throws InterruptedException, ExecutionException {
		final String uuid = uuid();
		try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
			// New line is a frame delimiter specific for xhr-polling"
			assertEquals(Status.OK, res.getStatusInfo());
			assertEquals("o\n", res.readEntity(String.class));
		}
		// After a session was established the server needs to accept requests for sending messages.
		// Xhr-polling accepts messages as a list of JSON-encoded strings.
		try (ClosableResponse res = post(target("000", uuid, XHR_SEND), json("[\"a\"]"))) {
			assertEquals(Status.NO_CONTENT, res.getStatusInfo());
			verifyEmptyEntity(res);
		}
		// We're using an echo service - we'll receive our message back. The message is encoded as an array 'a'.
		try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
			assertEquals(Status.OK, res.getStatusInfo());
			assertEquals("a[\"a\"]\n", res.readEntity(String.class));
		}
		// Sending messages to not existing sessions is invalid.
		try (ClosableResponse res = post(target("000", "bad_session", XHR_SEND), json("[\"a\"]"))) {
			verify404(XHR_SEND, res);
		}
		// The session must time out after 5 seconds of not having a receiving connection. The server must send a
		// heartbeat frame every 25 seconds. The heartbeat frame contains a single h character. This delay may be
		// configurable.
		// TODO
		// The server must not allow two receiving connections to wait on a single session. In such case the server must
		// send a close frame to the new connection.
		for (int i = 0; i < 10; i++) {
			try (ClosableResponse res = post(target("000", uuid, XHR_SEND), json("[\"xxxxxx\"]"))) {
				assertEquals(Status.NO_CONTENT, res.getStatusInfo());
			}
		}
		// Due to the time it takes for an async request to be scheduled it might actually be the one that returns the
		// 'another connection still open' error. Therefore we need to check both.
		final Future<Response> asyncFuture = target("000", uuid, XHR).request().async().post(json(null));
		try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
			assertEquals(Status.OK, res.getStatusInfo());
			final String resPayload = res.readEntity(String.class);
			try (ClosableResponse asyncRes = closable(asyncFuture.get())) {
				assertEquals(Status.OK, asyncRes.getStatusInfo());
				final String asyncResPayload = asyncRes.readEntity(String.class);
				if (ENABLE_CONCURRENT_REQUESTS_TEST) {
					final String expectedError = "c[2010,\"Another connection still open\"]\n";
					if (!expectedError.equals(resPayload) && !expectedError.equals(asyncResPayload)) {
						fail("Neither response had '" + expectedError + "'! [blocking=" + resPayload + ",async=" + asyncResPayload + "]");
					}
					final String expected = "a[\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\"]\n";
					if (!expected.equals(resPayload) && !expected.equals(asyncResPayload)) {
						fail("Neither response had '" + expected + "'! [blocking=" + resPayload + ",async=" + asyncResPayload + "]");
					}
				}
			}
		} finally {
			asyncFuture.cancel(true);
		}
	}
}
}
// Due to the time it takes for an async request to be scheduled it might actually be the one that returns the
// 'another connection still open' error. Therefore we need to check both.
final Future<Response> asyncFuture = target("000", uuid, XHR).request().async().post(json(null));
try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
// heartbeat frame every 25 seconds. The heartbeat frame contains a single h character. This delay may be
// configurable.
// TODO
// The server must not allow two receiving connections to wait on a single session. In such case the server must
// send a close frame to the new connection.
for (int i = 0; i < 10; i++) {
try (ClosableResponse res = post(target("000", uuid, XHR_SEND), json("[\"xxxxxx\"]"))) {
assertEquals(Status.NO_CONTENT, res.getStatusInfo());
}
}
// Due to the time it takes for an async request to be scheduled it might actually be the one that returns the
// 'another connection still open' error. Therefore we need to check both.
final Future<Response> asyncFuture = target("000", uuid, XHR).request().async().post(json(null));
try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
assertEquals(Status.OK, res.getStatusInfo());
final String resPayload = res.readEntity(String.class);
try (ClosableResponse asyncRes = closable(asyncFuture.get())) {
assertEquals(Status.OK, asyncRes.getStatusInfo());
final String asyncResPayload = asyncRes.readEntity(String.class);
if (ENABLE_CONCURRENT_REQUESTS_TEST) {
final String expectedError = "c[2010,\"Another connection still open\"]\n";
if (!expectedError.equals(resPayload) && !expectedError.equals(asyncResPayload)) {
// We're using an echo service - we'll receive our message back. The message is encoded as an array 'a'.
try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
assertEquals(Status.OK, res.getStatusInfo());
assertEquals("a[\"a\"]\n", res.readEntity(String.class));
}
// Sending messages to not existing sessions is invalid.
try (ClosableResponse res = post(target("000", "bad_session", XHR_SEND), json("[\"a\"]"))) {
verify404(XHR_SEND, res);
}
// The session must time out after 5 seconds of not having a receiving connection. The server must send a
// heartbeat frame every 25 seconds. The heartbeat frame contains a single h character. This delay may be
// configurable.
// TODO
// The server must not allow two receiving connections to wait on a single session. In such case the server must
// send a close frame to the new connection.
for (int i = 0; i < 10; i++) {
try (ClosableResponse res = post(target("000", uuid, XHR_SEND), json("[\"xxxxxx\"]"))) {
assertEquals(Status.NO_CONTENT, res.getStatusInfo());
}
}
// Due to the time it takes for an async request to be scheduled it might actually be the one that returns the
// 'another connection still open' error. Therefore we need to check both.
final Future<Response> asyncFuture = target("000", uuid, XHR).request().async().post(json(null));
try (ClosableResponse res = post(target("000", uuid, XHR), json(null))) {
assertEquals(Status.OK, res.getStatusInfo());
final String resPayload = res.readEntity(String.class);
try (ClosableResponse asyncRes = closable(asyncFuture.get())) {
assertEquals(Status.OK, asyncRes.getStatusInfo());
final String asyncResPayload = asyncRes.readEntity(String.class);
if (ENABLE_CONCURRENT_REQUESTS_TEST) {
final String expectedError = "c[2010,\"Another connection still open\"]\n";
if (!expectedError.equals(resPayload) && !expectedError.equals(asyncResPayload)) {
fail("Neither response had '" + expectedError + "'! [blocking=" + resPayload + ",async=" + asyncResPayload + "]");
}
final String expected = "a[\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\",\"xxxxxx\"]\n";
if (!expected.equals(resPayload) && !expected.equals(asyncResPayload)) {
fail("Neither response had '" + expected + "'! [blocking=" + resPayload + ",async=" + asyncResPayload + "]");
}
}
}
} finally {
asyncFuture.cancel(true);