Source:
<code>public boolean handleApiPersistentConnection(HttpMessage msg, HttpInputStream httpIn, HttpOutputStream httpOut, String name, JSONObject params) throws ApiException { if (PCONN_WAIT_FOR_HTTP_BREAK.equals(name)) { int poll = params.optInt(PARAM_POLL, 500); int keepAlive = params.optInt(PARAM_KEEP_ALIVE, -1); try { String contentType; int nextKeepAlive = keepAlive * 1000; int alive = 0; if (keepAlive > 0) { contentType = "text/plain"; } else { contentType = "text/event-stream"; } msg.setResponseHeader(API.getDefaultResponseHeader(contentType, -1)); msg.getResponseHeader().setHeader("Connection", "keep-alive"); <START> <END> httpOut.write(msg.getResponseHeader()); while (true) { Message brkMsg = extension.getBreakpointManagementInterface().getMessage(); if (brkMsg != null && brkMsg instanceof HttpMessage) { String event; HttpMessage httpMsg = (HttpMessage)brkMsg; JSONObject jo = new JSONObject(); if (extension.getBreakpointManagementInterface().isRequest()) { event = "httpRequest"; jo.put("header", httpMsg.getRequestHeader().toString()); jo.put("body", httpMsg.getRequestBody().toString()); } else { event = "httpResponse"; jo.put("header", httpMsg.getResponseHeader().toString()); jo.put("body", httpMsg.getResponseBody().toString()); } httpOut.write("event: " + event + "\n"); httpOut.write("data: " + jo.toString() + "\n\n"); httpOut.flush(); break; } try { Thread.sleep(poll); alive += poll; } catch (InterruptedException e) { } if (keepAlive > 0 && alive > nextKeepAlive) { httpOut.write("event: keepalive\n"); httpOut.write("data: {}\n\n"); httpOut.flush(); nextKeepAlive = alive + (keepAlive * 1000); } } } catch (IOException e) { } finally { httpOut.close(); httpIn.close(); } return true; } throw new ApiException(ApiException.Type.BAD_PCONN); }</code><technical_language>constants HttpHeader.CONNECTION HttpHeader._KEEP_ALIVE</technical_language>

Target:
public void handleApiPersistentConnection(HttpMessage msg, HttpInputStream httpIn, HttpOutputStream httpOut, String name, JSONObject params) throws ApiException { if (PCONN_WAIT_FOR_HTTP_BREAK.equals(name)) { int poll = params.optInt(PARAM_POLL, 500); int keepAlive = params.optInt(PARAM_KEEP_ALIVE, -1); try { String contentType; int nextKeepAlive = keepAlive * 1000; int alive = 0; if (keepAlive > 0) { contentType = "text/plain"; } else { contentType = "text/event-stream"; } msg.setResponseHeader(API.getDefaultResponseHeader(contentType, -1)); msg.getResponseHeader().setHeader(HttpHeader.CONNECTION, HttpHeader._KEEP_ALIVE); httpOut.write(msg.getResponseHeader()); while (true) { Message brkMsg = extension.getBreakpointManagementInterface().getMessage(); if (brkMsg != null && brkMsg instanceof HttpMessage) { String event; HttpMessage httpMsg = (HttpMessage)brkMsg; JSONObject jo = new JSONObject(); if (extension.getBreakpointManagementInterface().isRequest()) { event = "httpRequest"; jo.put("header", httpMsg.getRequestHeader().toString()); jo.put("body", httpMsg.getRequestBody().toString()); } else { event = "httpResponse"; jo.put("header", httpMsg.getResponseHeader().toString()); jo.put("body", httpMsg.getResponseBody().toString()); } httpOut.write("event: " + event + "\n"); httpOut.write("data: " + jo.toString() + "\n\n"); httpOut.flush(); break; } try { Thread.sleep(poll); alive += poll; } catch (InterruptedException e) { } if (keepAlive > 0 && alive > nextKeepAlive) { httpOut.write("event: keepalive\n"); httpOut.write("data: {}\n\n"); httpOut.flush(); nextKeepAlive = alive + (keepAlive * 1000); } } } catch (IOException e) { } finally { httpOut.close(); httpIn.close(); } return; } throw new ApiException(ApiException.Type.BAD_PCONN); }