private void expireConnect(ClientDelegate client, long time) { String targetId = client.getTargetId(); logger.info( "Client with targetId {} missing, last seen {} ms ago, closing it", targetId, System.currentTimeMillis() - time); client.close(); // If the client expired, means that it did not connect, // so there no request to resume, and we cleanup here // (while normally this cleanup is done in serviceConnect()) unschedule(targetId); gateway.removeClientDelegate(targetId); }
private void flush( ClientDelegate client, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException { List<RHTTPRequest> requests = client.process(httpRequest); if (requests != null) { // Schedule before sending the requests, to avoid that the remote client // reconnects before we have scheduled the expiration timeout. if (!client.isClosed()) schedule(client); ServletOutputStream output = httpResponse.getOutputStream(); for (RHTTPRequest request : requests) output.write(request.getFrameBytes()); // I could count the framed bytes of all requests and set a Content-Length header, // but the implementation of ServletOutputStream takes care of everything: // if the request was HTTP/1.1, then flushing result in a chunked response, but the // client know how to handle it; if the request was HTTP/1.0, then no chunking. // To avoid chunking in HTTP/1.1 I must set the Content-Length header. output.flush(); logger.debug("Delivered to device {} requests {} ", client.getTargetId(), requests); } }
private void schedule(ClientDelegate client) { Future<?> task = scheduler.schedule(new ClientExpirationTask(client), clientTimeout, TimeUnit.MILLISECONDS); Future<?> existing = expirations.put(client.getTargetId(), task); assert existing == null; }