2016-02-02 9 views
1

СценарийAndroid HttpURLConnection ж Persistent Connection

Пользователи должны войти на сервер с этим приложением. Позже в приложении нам нужно проверить их статус входа на сервер. Мы использовали это, отслеживая последний использованный HttpClient. Недавно мы переключились на HttpUrlConnection, но так называемые постоянные соединения не работают.

Вопрос

Я написал этот тест приложение, чтобы увидеть, если соединения были стойкими. Я возвращаю xml обратно с обоих URL-адресов, но соединение не ведет себя так, как будто оно последовательное. Как я могу заставить это работать?

Примечание: Все работает как ожидается, если вы перейдете на страницу . Введите URL-адрес в браузере, а затем перейдите на адрес GetUserInfo в том же браузере.

MainActivity.java

package com.mediajackagency.test; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URI; 
import java.net.URL; 

public class MainActivity extends AppCompatActivity { 

    public Button signInBtn = null; 
    public Button getUserInfoBtn = null; 
    public TextView xmlTextView = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     this.xmlTextView = (TextView)findViewById(R.id.xmlTxtView); 

     this.signInBtn = (Button)findViewById(R.id.signInBtn); 
     this.signInBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       AsyncTask task = new AsyncTask() { 
        @Override 
        protected Object doInBackground(Object[] params) { 
         String xml = loadUrl("https://www.fake.site/Login?userName=test&password=pass123"); 

         return xml; 
        } 

        @Override 
        protected void onPostExecute(Object o) { 
         super.onPostExecute(o); 
         xmlTextView.setText(o.toString()); 
        } 
       }; 
       task.execute(); 
      } 
     }); 

     this.getUserInfoBtn = (Button)findViewById(R.id.getUserInfoBtn); 
     this.getUserInfoBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       AsyncTask task = new AsyncTask() { 
        @Override 
        protected Object doInBackground(Object[] params) { 
         String xml = loadUrl("https://www.fake.site/GetCurrentUser"); 

         return xml; 
        } 

        @Override 
        protected void onPostExecute(Object o) { 
         super.onPostExecute(o); 
         xmlTextView.setText(o.toString()); 
        } 
       }; 
       task.execute(); 
      } 
     }); 
    } 

    public String loadUrl(String url) { 
     URI uri = MainActivity.encodeUrl(url); 
     Log.i("XMLParser", "Get URL: " + url); 

     String xml = null; 
     URL link; 
     BufferedReader reader = null; 
     StringBuilder stringBuilder = null; 
     InputStream is = null; 
     HttpURLConnection connection = null; 

     try { 
      link = new URL(url); 
      connection = (HttpURLConnection) link.openConnection(); 
      connection.setRequestMethod("GET"); 
      connection.connect(); 

      is = connection.getInputStream(); 
      reader = new BufferedReader(new InputStreamReader(is)); 
      stringBuilder = new StringBuilder(); 

      String line = null; 
      while ((line = reader.readLine()) != null) 
      { 
       stringBuilder.append(line + "\r"); 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (reader != null) { 
       try { 
        if(reader != null) reader.close(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

       try { 
        if(is != null) is.close(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

       try { 
        if(connection != null) connection.disconnect(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     try { 
      xml = stringBuilder.toString(); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
     return xml; 
    } 

    public static URI encodeUrl(String url) { 
     URL urlObject; 
     URI uri = null; 
     try { 
      urlObject = new URL(url); 
      uri = new URI(urlObject.getProtocol(), urlObject.getUserInfo(), urlObject.getHost(), 
        urlObject.getPort(), urlObject.getPath(), urlObject.getQuery(), urlObject.getRef()); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return uri; 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 
+0

В вашем примере кода много шума. все это сводится к тому, чтобы оставить соединение открытым (после утверждения try нет окончательного блока), и в основном, что вы действительно хотите иметь доступный HTTP-ресурс в течение всего срока службы приложения. этот вопрос вполне мог бы устранить все несущественные идеи и очистить комментарии. это отличный вопрос! хотя, очень уродливо читать;) cheers – activedecay

+0

удалить пакет/импорт. замените catch {e.printStackTrace();} с catch (исключение XException) {}, удалите записи журнала, удалите комментарии, которые не относятся к вопросу, и, наконец, добавьте комментарии, которые относятся к вопросу. – activedecay

ответ

2

решаемые с печеньем

После дней/часов работы на этом я обнаружил, что постоянные соединения (http.keepalive) с HttpUrlConnection не все это трещины до быть:

1) Вам необходимо убедиться, что InputStream и HttpUrlConnection не включены, прежде чем вы сможете повторно использовать соединение и даже тогда не всегда может быть повторно использован.

2) Открытые TCP-соединения могут быть ресурсными свиньями.

После обнаружения & проверка идеи using cookies with HttpUrlConnection Я решил пойти по этому маршруту, поскольку он в основном более звучит и работает лучше, чем моя оригинальная идея.