Von meiner Android App wollte ich Daten auf dem Server veröffentlichen und die Antwort zurückbekommen, sie verarbeiten, dann zurücksenden und eine weitere Anfrage erhalten. Da es sich um eine kontinuierliche Kommunikation bis keine Reaktion mehr auf den Prozess handelt, bevorzuge ich mit HttpURLConnection
http.keepAlive = true
.Warum sendet Android HttpURLConnection nicht zurück FIN?
Und mein Versuch Buchse wieder zu verwenden ist erfolgreich, aber die Probleme, die ich sind bin vor:
- ich von Client (Android App) In der Nähe zu initiieren bin versucht, denn wenn die Beendigung von dann Server-Server gestartet geht zu
TIME_WAIT
Zustand. Und ich möchte nicht, dass mein Server in diesen Zustand wechselt, daher bevorzugte ich, dass mein Client die Kündigung einleitete. Aber leider Ich finde keine geeignete Art und Weise, es zu tun mitHttpURLConnection
- Nach Stunden des Suchens gab ich tun die oben Versuch und ging mit von Server Schließen Einleitung basierend auf
keepalivetimeout
, aber wenn Server sendetFIN
, antwortet Kunde mit nurACK
, wegen dieser Verbindung aufFIN_WAIT_2
gehalten in Server undCLOSE_WAIT
im Agenten.
Source Code:
private HttpStatus communicateWithMDMServer(String httpUrl, String dataToSend, boolean keepAlive) {
HttpStatus status = new HttpStatus(HTTP_STATUS_FAILURE);
try {
initializeConnection(httpUrl,keepAlive);
postDataToConnection(connection, dataToSend);
status = readDataFromConnection(connection);
} catch (MalformedURLException e) {
MDMLogger.error("Failed to send data to server as the URL provided is not valid "+ e.getMessage()+"\n");
e.printStackTrace();
} catch (IOException e) {
MDMLogger.error("Failed to send the status to the server : IOException "+ e.getMessage()+"\n"+e.getStackTrace());
e.printStackTrace();
readErrorStreamAndPrint(connection);
}
connection.disconnect();
return status;
}
/**
* API to close connection, calling this will not force the connection to shutdown
* this will work based on the Connection header set.
* @param connection
*/
public void closeConnection(){
if(connection != null){
connection.disconnect();
}
}
/**
* Used to initialize the HttpURLConnection for the given url
* All properties required for connection are preset here
* Connection Time Out : 20 Seconds
* Connection Type : keep alive
* Content Type : application/json;charset=UTF-8
* And also All certificates will be evaluated as Valid.[ TODO will be removed soon]
* @param httpUrl
* @return
* @throws MalformedURLException
* @throws IOException
*/
private void initializeConnection(String httpUrl, boolean keepAlive) throws MalformedURLException, IOException{
URL url = new URL(httpUrl);
connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(20000);
connection.setReadTimeout(20000);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST"); //NO I18N
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); //NO I18N
connection.setRequestProperty("Connection", "Keep-Alive"); //NO I18N
}
/**
* API to post data to given connection
* call to this API will close the @OutputStream
* @param connection
* @param data
* @throws IOException
*/
private void postDataToConnection(URLConnection connection , String data) throws IOException{
OutputStream outStream = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outStream));
writer.write(data);
writer.flush();
writer.close();
outStream.close();
}
/**
* API to read error stream and log
* @param connection
*/
private void readErrorStreamAndPrint(URLConnection connection){
try{
InputStream inStream = ((HttpURLConnection) connection).getErrorStream();
String responseData = "";
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(inStream));
while ((line=br.readLine()) != null) {
responseData+=line;
}
MDMLogger.error("ErrorStream Says "+responseData);
} catch (IOException ioe) {
MDMLogger.debug("Exception on reading ErrorStream");
}
}
/**
* API to read data from given connection and return {@code com.manageengine.mdm.framework.communication.HttpStatus}
* call to this API will close the @InputStream
* @param connection
* @return
* @throws IOException
*/
private HttpStatus readDataFromConnection(URLConnection connection) throws IOException{
HttpStatus status = new HttpStatus(HTTP_STATUS_FAILURE);
int responseCode=((HttpURLConnection) connection).getResponseCode();
MDMLogger.info("Response Code: "+responseCode);
InputStream inStream = connection.getInputStream();
MDMLogger.info("Response Header: "+connection.getHeaderFields());
String responseData = "";
if (responseCode == HttpURLConnection.HTTP_OK) {
responseData = readStreamAsString(inStream);
status.setStatus(HTTP_STATUS_SUCCESS);
status.setUrlDataBuffer(responseData);
MDMLogger.info("communicateWithMDMServer : Response is \n" + status.getUrlDataBuffer());
MDMLogger.info("Successfully send the data to server and received success response ");
}
else {
status.setStatus(HTTP_STATUS_FAILURE);
MDMLogger.error("Data sent successfully but failed to get the response and the response code is : " + responseCode);
}
inStream.close();
return status;
}
/**
* Read the InputStream to String until EOF
* Call to this API will not close @InputStream
* @param inStream
* @return
* @throws IOException
*/
private String readStreamAsString(InputStream inStream) throws IOException{
StringBuilder responseData = new StringBuilder();
String line;
BufferedReader br=new BufferedReader(new InputStreamReader(inStream));
while ((line=br.readLine()) != null) {
responseData.append(line);
}
return responseData.toString();
}
Kann jemand helfen?
Der 'geeignete Weg, es mit 'HttpURLConnection' zu tun ist' HttpURLConnection.disconnect(). 'Aber es ist nur ein Hinweis. – EJP
@EJP Ich habe disconnect() am Ende der Transaktion verwendet, aber ich finde keinen Unterschied, können Sie bitte mehr ausarbeiten. –