SlideShare uma empresa Scribd logo
1 de 106
Baixar para ler offline
А л е к с а н д р З а це п и н
разработчик, Мобильная почта/Почта
     a l e x a n d e r. z a t s e p i n @ m a i l . r u
Работа с сетью в Android
800 000
700 000
600 000
500 000
400 000
                                      Приложения
300 000
200 000
100 000
      0
          2009   2010   2011   2012
Более 800000 приложений
Server
Сокеты
                       Server


Client            Server
Socket            Socket
Частые опросы (Polling)
                          Server
Длинные опросы (Long-Polling)
                           Server
Пуш-нотификации

      System      Long-polling
                                  GCM
                  subscribes
                   regId
App




                                 Server
Виды возможных сетевых взаимодействий в Андроид
1. Сокеты
2. Длинные опросы (Long-polling)
3. Пуш-нотификации (Google Cloud Messaging(GCM))
4. Частые опросы сервера (Polling)
Виды возможных сетевых взаимодействий в Андроид
1. Сокеты
2. Длинные опросы (Long-polling)
3. Пуш-нотификации (Google Cloud Messaging(GCM))
4. Частые опросы сервера (Polling)
Виды возможных сетевых взаимодействий в Андроид
1. Сокеты
2. Длинные опросы (Long-polling)
3. Пуш-нотификации (Google Cloud Messaging(GCM))
4. Частые опросы сервера (Polling)
HttpUrlConnection   Server
HttpUrlConnection          Server




                   HttpContext
             HttpRequest

             HttpEntity
HttpClient
                                 Server
             HttpResponse
              HttpEntity
HttpUrlConnection connection = null;
try {
  URL url = new URL("http://example.com");
  connection = (HttpUrlConnection) url.openConnection();
HttpUrlConnection connection = null;
try {
  URL url = new URL("http://example.com");
  connection = (HttpUrlConnection) url.openConnection();
  connection.setRequestMethod("GET");
  connection.setRequestProperty("Accept", "text/plain");
HttpUrlConnection connection = null;
try {
  URL url = new URL("http://example.com");
  connection = (HttpUrlConnection) url.openConnection();
  connection.setRequestMethod("GET");
  connection.setRequestProperty("Accept", "text/plain");
  connection.connect();
HttpUrlConnection connection = null;
try {
  URL url = new URL("http://example.com");
  connection = (HttpUrlConnection) url.openConnection();
  connection.setRequestMethod("GET");
  connection.setRequestProperty("Accept", "text/plain");
  connection.connect();
  int statusCode = connection.getResponseCode();
  ...
HttpUrlConnection connection = null;
try {
  URL url = new URL("http://example.com");
  connection = (HttpUrlConnection) url.openConnection();
  connection.setRequestMethod("GET");
  connection.setRequestProperty("Accept", "text/plain");
  connection.connect();
  int statusCode = connection.getResponseCode();
  ...
  readTextFromServer();
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (connection != null) {
      connection.disconnect();
    }
}
try {
  HttpGet request = new HttpGet("http://example.com");
try {
  HttpGet request = new HttpGet("http://example.com");
  request.setHeader("Accept", "text/plain");
try {
  HttpGet request = new HttpGet("http://example.com");
  request.setHeader("Accept", "text/plain");
  HttpResponse response = getHttpClient().execute(request);
try {
  HttpGet request = new HttpGet("http://example.com");
  request.setHeader("Accept", "text/plain");
  HttpResponse response = getHttpClient().execute(request);
  int statusCode = response.getStatusLine().getStatusCode();
  ...
try {
  HttpGet request = new HttpGet("http://example.com");
  request.setHeader("Accept", "text/plain");
  HttpResponse response = getHttpClient().execute(request);
  int statusCode = response.getStatusLine().getStatusCode();
  ...
  return EntityUtils.toString(response.getEntity());
} catch (Exception e) {
    e.printStackTrace();
}
HttpUrlConnection          Server




                   HttpContext
             HttpRequest

             HttpEntity
HttpClient
                                 Server
             HttpResponse
              HttpEntity
HttpUrlConnection

HttpUrlConnection
                    Server


       …
HttpUrlConnection
      App
HttpUrlConnection

      HttpUrlConnection
                                 Server


              …
      HttpUrlConnection
             App

                   HttpContext
             HttpRequest

             HttpEntity
HttpClient
                                 Server
             HttpResponse
              HttpEntity



             App
Потокобезопасность

                       1
                   2

                           HttpUrlConnection
        Thread N
Потокобезопасность

                       1
                   2

                           HttpUrlConnection
        Thread N
Потокобезопасность

                     HttpClient
                 1
             2


  Thread N
Потокобезопасность
                                 HttpClient
              1
             2    ThreadSafeClientConnManager



  Thread N




                  1
                  connection 1
                                   ...   connection N
                  2
                  connection 2
Потокобезопасность
static {
  ...
  HttpParams params = new BasicHttpParams();
  ConnManagerParams.setMaxTotalConnections(params, 10);
Потокобезопасность
static {
  ...
  HttpParams params = new BasicHttpParams();
  ConnManagerParams.setMaxTotalConnections(params, 10);
  ConnManagerParams.setMaxConnectionsPerRoute(params,
      new ConnPerRoute() {
        @Override
        public int getMaxForRoute(HttpRoute route) {
          return 5;
        }
      });
Потокобезопасность
static {
  ...
  HttpParams params = new BasicHttpParams();
  ConnManagerParams.setMaxTotalConnections(params, 10);
  ConnManagerParams.setMaxConnectionsPerRoute(params,
      new ConnPerRoute() {
        @Override
        public int getMaxForRoute(HttpRoute route) {
          return 5;
        }
      });
  ThreadSafeClientConnManager cm =
    new ThreadSafeClientConnManager(params, schemeRegistry);
}
Потокобезопасность
static {
  ...
  HttpParams params = new BasicHttpParams();
  ConnManagerParams.setMaxTotalConnections(params, 10);
  ConnManagerParams.setMaxConnectionsPerRoute(params,
      new ConnPerRoute() {
        @Override
        public int getMaxForRoute(HttpRoute route) {
          return 5;
        }
      });
  ThreadSafeClientConnManager cm =
    new ThreadSafeClientConnManager(params, schemeRegistry);
  httpClient = new DefaultHttpClient(cm, params);
}
Application

request   request   ...   request   request




                Server
Application

request   request   ...   request   request




 TCP       TCP             TCP       TCP



                 Server
Application

request       request   ...   request       request




 TCP      +    TCP      …+…    TCP      +    TCP      = traffic



                     Server
Keep-alive cоединение
Keep-alive cоединение

               Application

request   request    ...   request   request




                    TCP



                Server
Keep-alive cоединение

                   Application

request       request    ...   request       request




                        TCP
          +             …+…              +             = traffic

                    Server
Номер        Время(ms)
запроса   KeepAlive = false

  1             2098
  2             2157
  3             2037
  4             2096
  5             1944
  6             2055
  7             1865
  8             2119
  9             1986
  10            1965
               ≈2032,2
Номер        Время(ms)           Время(ms)
запроса   KeepAlive = false   KeepAlive = true

  1             2098                2023
  2             2157                1604
  3             2037                1698
  4             2096                1774
  5             1944                1173
  6             2055                1573
  7             1865                1683
  8             2119                1670
  9             1986                1666
  10            1965                1541
               ≈2032,2            ≈1700,5
Номер        Время(ms)           Время(ms)
запроса   KeepAlive = false   KeepAlive = true

  1             2098                2023
  2             2157                1604
  3             2037                1698
  4             2096                1774
                                                 На 16,2% быстрее!
  5             1944                1173
  6             2055                1573
  7             1865                1683
  8             2119                1670
  9             1986                1666
  10            1965                1541
               ≈2032,2            ≈1700,5
Keep Alive Duration
Keep Alive Duration




𝐭      App




    𝐭 − 𝐭𝐢𝐦𝐞
Keep Alive Duration
               request1




𝐭      App




    𝐭 − 𝐭𝐢𝐦𝐞
Keep Alive Duration
               request1


                          TCP

𝐭      App                      Server




    𝐭 − 𝐭𝐢𝐦𝐞
Keep Alive Duration
               request1

               request2   TCP

𝐭      App                      Server




    𝐭 − 𝐭𝐢𝐦𝐞
Keep Alive Duration
               request1

               request2   TCP
               request3
𝐭      App                      Server




    𝐭 − 𝐭𝐢𝐦𝐞
Keep Alive Duration
               request1

               request2   TCP
               request3
𝐭      App                      Server


               request4


    𝐭 − 𝐭𝐢𝐦𝐞
Keep Alive Duration
                  request1

                  request2    TCP
                  request3
𝐭      App                          Server
                 𝐭𝟑> 𝐝

                  request4


    𝐭 − 𝐭𝐢𝐦𝐞
    𝐝 − 𝐤𝐞𝐞𝐩 𝐚𝐥𝐢𝐯𝐞 𝐝𝐮𝐫𝐚𝐭𝐢𝐨𝐧
Keep Alive Duration
                  request1

                  request2    TCP
                  request3
𝐭      App                          Server
                 𝐭𝟑> 𝐝

                  request4    TCP


    𝐭 − 𝐭𝐢𝐦𝐞
    𝐝 − 𝐤𝐞𝐞𝐩 𝐚𝐥𝐢𝐯𝐞 𝐝𝐮𝐫𝐚𝐭𝐢𝐨𝐧
Keep Alive Duration
httpClient.setKeepAliveStrategy(
  new ConnectionKeepAliveStrategy() {

    @Override
    public long getKeepAliveDuration(HttpResponse response,
                                     HttpContext context){
      return KEEP_ALIVE_DURATION_MILLISECONDS;
    }
  });
Keep Alive Duration
Keep Alive Duration




if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO){
  System.setProperty("http.keepAlive", "false");
}
Keep Alive Duration




if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO){
  System.setProperty("http.keepAlive", "false");
}

Hе поддается настройке!(≈5 секунд)
try {
  ...
  InputStream is = connection.getInputStream();
  // Вычитывайте все данные из InputStream’a
  is.close();
} catch (Exception e) {
    try {
      InputStream es = connection.getErrorStream();
      // Вычитывайте все данные из InputStream’a
      es.close();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}
Гзипование траффика
Гзипование траффика
...
InputStream is = response.getEntity().getContent();
Header contentEncoding =
  response.getFirstHeader("Content-Encoding");
Гзипование траффика
...
InputStream is = response.getEntity().getContent();
Header contentEncoding =
  response.getFirstHeader("Content-Encoding");
if (contentEncoding != null
    && contentEncoding.getValue().equalsIgnoreCase("gzip"))
Гзипование траффика
...
InputStream is = response.getEntity().getContent();
Header contentEncoding =
  response.getFirstHeader("Content-Encoding");
if (contentEncoding != null
    && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
    is = new GZIPInputStream(is);
}
...
Гзипование траффика
...
InputStream is = connection.getInputStream();
String contentEncoding = connection.getContentEncoding();
if ("gzip".equalsIgnoreCase(contentEncoding)) {
  is = new GZIPInputStream(connection.getInputStream());
}
...
Гзипование траффика
Гзипование траффика




          Не полагайтесь на Content-Length!
Управление куками
Управление куками



Set-Cookie: name=value; expires=date; path=/; domain=.example.com
Управление куками
...
CookieStore cs = getHttpClient().getCookieStore();
BasicClientCookie c = new BasicClientCookie("Mpop", cookie);
c.setDomain(".mail.ru");
cs.addCookie(c);
...
Управление куками
...
String cookieHeader = session.getCookieHeader();
сonnection.setRequestProperty("Cookie", cookieHeader);
...
Установка куки в WebView
Application
Установка куки в WebView
Application                              Browser



 WebView




 WebView
Установка куки в WebView
Application                                                Browser
              CookieSyncManager.createInstance(context);

 WebView




 WebView
Установка куки в WebView
Application                                                        Browser
              CookieSyncManager.createInstance(context);
              CookieManager.getInstance().setAcceptCookie(true);
 WebView




 WebView
Установка куки в WebView
Application                                                              Browser
              CookieSyncManager.createInstance(context);
              CookieManager.getInstance().setAcceptCookie(true);
              CookieManager.getInstance().setCookie("mail.ru",cookie);
 WebView




 WebView
Установка куки в WebView
Application                                                               Browser
              CookieSyncManager.createInstance(context);
              CookieManager.getInstance().setAcceptCookie(true);
              CookieManager.getInstance().setCookie("mail.ru",cookie);
 WebView
              //for API level >= 15
              CookieManager.getInstance().setCookie(".mail.ru",cookie);


 WebView
Установка куки в WebView
Application                                                              Browser
              CookieSyncManager.createInstance(context);
              CookieManager.getInstance().setAcceptCookie(true);
              CookieManager.getInstance().setCookie("mail.ru",cookie);
 WebView
              //for API level >= 15
              CookieManager.getInstance().setCookie(".mail.ru",cookie)
              CookieSyncManager.getInstance().sync();

 WebView
Установка куки в WebView
Application                                                              Browser
              CookieSyncManager.createInstance(context);
              CookieManager.getInstance().setAcceptCookie(true);
              CookieManager.getInstance().setCookie("mail.ru",cookie);
 WebView
 cookie       //for API level >= 15
              CookieManager.getInstance().setCookie(".mail.ru",cookie)
              CookieSyncManager.getInstance().sync();

 WebView
 cookie
Установка куки в WebView
Application                                                              Browser
              CookieSyncManager.createInstance(context);
              CookieManager.getInstance().setAcceptCookie(true);
              CookieManager.getInstance().setCookie("mail.ru",cookie);
 WebView
 cookie       //for API level >= 15
              CookieManager.getInstance().setCookie(".mail.ru",cookie)
              CookieSyncManager.getInstance().sync();

 WebView
 cookie
Защищенное соединение (https)
Защищенное соединение (https)

Application                    Server




                  CA
Защищенное соединение (https)

Application                      Server




                  CA     Signs certificate
Защищенное соединение (https)
                request
Application                       Server




                  CA      Signs certificate
Защищенное соединение (https)
                 request
Application                          Server
                                   Private key
               Certificate
                Public key




                   CA        Signs certificate
Защищенное соединение (https)
                       request
Application                                Server
                                         Private key
                     Certificate
                      Public key




Checks certificate       CA        Signs certificate
Защищенное соединение (https)
                       request
Application                                 Server
                                          Private key
                     Certificate
                      Public key

                 Random symmetric key




Checks certificate       CA         Signs certificate
Защищенное соединение (https)
                         request
Application                                      Server
                                               Private key
                       Certificate
                        Public key

                 Random symmetric key

                     Data transferring


Checks certificate         CA            Signs certificate
Варианты реализации https
1. KeyChain API на платформах >= 4.0
Варианты реализации https
1. KeyChain API на платформах >= 4.0
2. На платформах < 4.0 надо создавать локальное хранилище ключей
Варианты реализации https
1. KeyChain API на платформах >= 4.0
2. На платформах < 4.0 надо создавать локальное хранилище ключей
3. Доверять всем сертификатам
Https на платформа < 4.0
...
TrustManagerFactory tmf =
      TrustManagerFactory.getInstance(algorithm);
KeyStore keyStore = KeyStore.getInstance("BKS");
InputStream in =
      context.getResources().openRawResource(mykeystore);
keyStore.load(in, "mysecret".toCharArray());
in.close();
tmf.init(keyStore);
SSLContext sslc = SSLContext.getInstance("TLS");
sslc.init(null, tmf.getTrustManagers(),new SecureRandom());
...
Https на платформа < 4.0
private SSLSocketFactory createSslSocketFactory() {
  SSLSocketFactory sf = null;
  try {
    KeyStore keyStore = KeyStore.getInstance("BKS");
    InputStream in =
    context.getResources().openRawResource(mykeystore);
    keyStore.load(in, "mysecret".toCharArray());
    in.close();
    sf = new SSLSocketFactory(keyStore);
    sf.setHostnameVerifier(STRICT_HOSTNAME_VERIFIER);
  } catch (Exception e) {
    e.printStackTrace();
  }
  return sf;
}
Доверять всем сертификатам
private class DummyHostnameVerifier implements HostnameVerifier{

    @Override
    public boolean verify(String hostname, SSLSession session) {
      return true;
    }
}
Доверять всем сертификатам
private class DummyTrustManager implements X509TrustManager{

  @Override
  public void checkClientTrusted(X509Certificate[] chain, String authType)
                                            throws CertificateException {
    //empty
  }

  @Override
  public void checkServerTrusted(X509Certificate[] chain, String authType)
                                            throws CertificateException {
    //empty
  }
 ...
}
Полезные инструменты
1.   StrictMode
2.   ConnectivityManager
3.   DDMS Network Traffic Tool
4.   Rest-client
5.   Wireshark
Полезные инструменты
1.   StrictMode
2.   ConnectivityManager
3.   DDMS Network Traffic Tool
4.   Rest-client
5.   Wireshark
Полезные инструменты
1.   StrictMode
2.   ConnectivityManager
3.   DDMS Network Traffic Tool
4.   Rest-client
5.   Wireshark
Полезные инструменты
1.   StrictMode
2.   ConnectivityManager
3.   DDMS Network Traffic Tool
4.   Rest-client
5.   Wireshark
Полезные инструменты
1.   StrictMode
2.   ConnectivityManager
3.   DDMS Network Traffic Tool
4.   Rest-client
5.   Wireshark
Полезные инструменты
1.   StrictMode
2.   ConnectivityManager
3.   DDMS Network Traffic Tool
4.   Rest-client
5.   Wireshark
Полезные ссылки
1.   KeyChain API – http://goo.gl/ICijf
2.   Создание локального хранилища ключей – http://goo.gl/5Surx
3.   Keep Alive - http://goo.gl/9cdlz
4.   Минимизация расхода батареи - http://goo.gl/DML0m
5.   Выполнение сетевых операций - http://goo.gl/GIVIs
А л е к с а н д р З а це п и н
разработчик, Мобильная почта/Почта
    a l e x a n d e r. z a t s e p i n @ m a i l . r u

Mais conteúdo relacionado

Destaque (12)

Kalugin balashov
Kalugin balashovKalugin balashov
Kalugin balashov
 
Perepelitsa
PerepelitsaPerepelitsa
Perepelitsa
 
Zamyakin
ZamyakinZamyakin
Zamyakin
 
Smirnov reverse-engineering-techforum
Smirnov reverse-engineering-techforumSmirnov reverse-engineering-techforum
Smirnov reverse-engineering-techforum
 
Haritonov
HaritonovHaritonov
Haritonov
 
Smirnov dependency-injection-techforum(1)
Smirnov dependency-injection-techforum(1)Smirnov dependency-injection-techforum(1)
Smirnov dependency-injection-techforum(1)
 
Platov
PlatovPlatov
Platov
 
A.pleshkov
A.pleshkovA.pleshkov
A.pleshkov
 
Zagursky
ZagurskyZagursky
Zagursky
 
Chudov
ChudovChudov
Chudov
 
Osipov
OsipovOsipov
Osipov
 
Kubasov
KubasovKubasov
Kubasov
 

Semelhante a Zacepin

Android осень 2013 лекция 4
Android осень 2013 лекция 4Android осень 2013 лекция 4
Android осень 2013 лекция 4Technopark
 
17 - Web-технологии. Real Time сообщения
17 - Web-технологии. Real Time сообщения17 - Web-технологии. Real Time сообщения
17 - Web-технологии. Real Time сообщенияRoman Brovko
 
Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...
Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...
Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...Fuenteovejuna
 
Асинхронные вызовы в .NET
Асинхронные вызовы в .NETАсинхронные вызовы в .NET
Асинхронные вызовы в .NETBonart
 
Wild Async .NET world: AID Kit for boy-scouts
Wild Async .NET world: AID Kit for boy-scoutsWild Async .NET world: AID Kit for boy-scouts
Wild Async .NET world: AID Kit for boy-scoutsHYS Enterprise
 
Тандемные DDoS-атаки (Артём Гавриченков)
Тандемные DDoS-атаки (Артём Гавриченков)Тандемные DDoS-атаки (Артём Гавриченков)
Тандемные DDoS-атаки (Артём Гавриченков)Ontico
 
Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...
Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...
Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...HLL
 
gRPC в продакшне для мобильных приложений
gRPC в продакшне для мобильных приложенийgRPC в продакшне для мобильных приложений
gRPC в продакшне для мобильных приложенийMad Devs
 
Eugene Lisitsky Web Sockets
Eugene Lisitsky Web SocketsEugene Lisitsky Web Sockets
Eugene Lisitsky Web Socketsguest092df8
 
Хватит писать инфраструктурный код
Хватит писать инфраструктурный кодХватит писать инфраструктурный код
Хватит писать инфраструктурный кодVadim Martynov
 
"Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F...
"Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F..."Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F...
"Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F...MoscowJS
 
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...it-people
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
Android - 11 - Multithreading
Android - 11 - MultithreadingAndroid - 11 - Multithreading
Android - 11 - MultithreadingNoveo
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыPlatonov Sergey
 

Semelhante a Zacepin (20)

Android осень 2013 лекция 4
Android осень 2013 лекция 4Android осень 2013 лекция 4
Android осень 2013 лекция 4
 
UA Mobile 2012
UA Mobile 2012UA Mobile 2012
UA Mobile 2012
 
17 - Web-технологии. Real Time сообщения
17 - Web-технологии. Real Time сообщения17 - Web-технологии. Real Time сообщения
17 - Web-технологии. Real Time сообщения
 
Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...
Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...
Тандемные DDoS-атаки. Проблематика уязвимостей в спецификации TCP IP (фундаме...
 
Асинхронные вызовы в .NET
Асинхронные вызовы в .NETАсинхронные вызовы в .NET
Асинхронные вызовы в .NET
 
Wild Async .NET world: AID Kit for boy-scouts
Wild Async .NET world: AID Kit for boy-scoutsWild Async .NET world: AID Kit for boy-scouts
Wild Async .NET world: AID Kit for boy-scouts
 
Тандемные DDoS-атаки (Артём Гавриченков)
Тандемные DDoS-атаки (Артём Гавриченков)Тандемные DDoS-атаки (Артём Гавриченков)
Тандемные DDoS-атаки (Артём Гавриченков)
 
Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...
Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...
Тандемные DDoS-атаки / Проблематика уязвимостей в спецификации TCP/IP (фундам...
 
gRPC в продакшне для мобильных приложений
gRPC в продакшне для мобильных приложенийgRPC в продакшне для мобильных приложений
gRPC в продакшне для мобильных приложений
 
Kharkov
KharkovKharkov
Kharkov
 
Eugene Lisitsky Web Sockets
Eugene Lisitsky Web SocketsEugene Lisitsky Web Sockets
Eugene Lisitsky Web Sockets
 
Periculum est in mora
Periculum est in moraPericulum est in mora
Periculum est in mora
 
Practical usage of RxJava 2
Practical usage of RxJava 2Practical usage of RxJava 2
Practical usage of RxJava 2
 
Хватит писать инфраструктурный код
Хватит писать инфраструктурный кодХватит писать инфраструктурный код
Хватит писать инфраструктурный код
 
"Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F...
"Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F..."Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F...
"Как перестать отлаживать асинхронный код и начать жить", Андрей Саломатин, F...
 
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
DUMP-2015 «Микросервисная архитектура в теории и на практике» Иван Бурмистров...
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
Web лекция 1
Web   лекция 1Web   лекция 1
Web лекция 1
 
Android - 11 - Multithreading
Android - 11 - MultithreadingAndroid - 11 - Multithreading
Android - 11 - Multithreading
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 

Mais de kuchinskaya

владимир габриелян
владимир габриелянвладимир габриелян
владимир габриелянkuchinskaya
 
чашкин иван
чашкин иванчашкин иван
чашкин иванkuchinskaya
 
сумин андрей
сумин андрейсумин андрей
сумин андрейkuchinskaya
 
митасов роман
митасов романмитасов роман
митасов романkuchinskaya
 
кренин владимир
кренин владимиркренин владимир
кренин владимирkuchinskaya
 
константин лебедев
константин лебедевконстантин лебедев
константин лебедевkuchinskaya
 
дыдыкин егор
дыдыкин егордыдыкин егор
дыдыкин егорkuchinskaya
 
ярослав рабоволюк
ярослав рабоволюкярослав рабоволюк
ярослав рабоволюкkuchinskaya
 
сергей спиридонов
сергей спиридоновсергей спиридонов
сергей спиридоновkuchinskaya
 
игорь ермаков
игорь ермаковигорь ермаков
игорь ермаковkuchinskaya
 
дмитрий юдин3
дмитрий юдин3дмитрий юдин3
дмитрий юдин3kuchinskaya
 

Mais de kuchinskaya (11)

владимир габриелян
владимир габриелянвладимир габриелян
владимир габриелян
 
чашкин иван
чашкин иванчашкин иван
чашкин иван
 
сумин андрей
сумин андрейсумин андрей
сумин андрей
 
митасов роман
митасов романмитасов роман
митасов роман
 
кренин владимир
кренин владимиркренин владимир
кренин владимир
 
константин лебедев
константин лебедевконстантин лебедев
константин лебедев
 
дыдыкин егор
дыдыкин егордыдыкин егор
дыдыкин егор
 
ярослав рабоволюк
ярослав рабоволюкярослав рабоволюк
ярослав рабоволюк
 
сергей спиридонов
сергей спиридоновсергей спиридонов
сергей спиридонов
 
игорь ермаков
игорь ермаковигорь ермаков
игорь ермаков
 
дмитрий юдин3
дмитрий юдин3дмитрий юдин3
дмитрий юдин3
 

Zacepin

  • 1. А л е к с а н д р З а це п и н разработчик, Мобильная почта/Почта a l e x a n d e r. z a t s e p i n @ m a i l . r u
  • 3. 800 000 700 000 600 000 500 000 400 000 Приложения 300 000 200 000 100 000 0 2009 2010 2011 2012
  • 6.
  • 7.
  • 8.
  • 9.
  • 10. Сокеты Server Client Server Socket Socket
  • 13. Пуш-нотификации System Long-polling GCM subscribes regId App Server
  • 14. Виды возможных сетевых взаимодействий в Андроид 1. Сокеты 2. Длинные опросы (Long-polling) 3. Пуш-нотификации (Google Cloud Messaging(GCM)) 4. Частые опросы сервера (Polling)
  • 15. Виды возможных сетевых взаимодействий в Андроид 1. Сокеты 2. Длинные опросы (Long-polling) 3. Пуш-нотификации (Google Cloud Messaging(GCM)) 4. Частые опросы сервера (Polling)
  • 16. Виды возможных сетевых взаимодействий в Андроид 1. Сокеты 2. Длинные опросы (Long-polling) 3. Пуш-нотификации (Google Cloud Messaging(GCM)) 4. Частые опросы сервера (Polling)
  • 18. HttpUrlConnection Server HttpContext HttpRequest HttpEntity HttpClient Server HttpResponse HttpEntity
  • 19. HttpUrlConnection connection = null; try { URL url = new URL("http://example.com"); connection = (HttpUrlConnection) url.openConnection();
  • 20. HttpUrlConnection connection = null; try { URL url = new URL("http://example.com"); connection = (HttpUrlConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "text/plain");
  • 21. HttpUrlConnection connection = null; try { URL url = new URL("http://example.com"); connection = (HttpUrlConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "text/plain"); connection.connect();
  • 22. HttpUrlConnection connection = null; try { URL url = new URL("http://example.com"); connection = (HttpUrlConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "text/plain"); connection.connect(); int statusCode = connection.getResponseCode(); ...
  • 23. HttpUrlConnection connection = null; try { URL url = new URL("http://example.com"); connection = (HttpUrlConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Accept", "text/plain"); connection.connect(); int statusCode = connection.getResponseCode(); ... readTextFromServer(); } catch (Exception e) { e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } }
  • 24. try { HttpGet request = new HttpGet("http://example.com");
  • 25. try { HttpGet request = new HttpGet("http://example.com"); request.setHeader("Accept", "text/plain");
  • 26. try { HttpGet request = new HttpGet("http://example.com"); request.setHeader("Accept", "text/plain"); HttpResponse response = getHttpClient().execute(request);
  • 27. try { HttpGet request = new HttpGet("http://example.com"); request.setHeader("Accept", "text/plain"); HttpResponse response = getHttpClient().execute(request); int statusCode = response.getStatusLine().getStatusCode(); ...
  • 28. try { HttpGet request = new HttpGet("http://example.com"); request.setHeader("Accept", "text/plain"); HttpResponse response = getHttpClient().execute(request); int statusCode = response.getStatusLine().getStatusCode(); ... return EntityUtils.toString(response.getEntity()); } catch (Exception e) { e.printStackTrace(); }
  • 29. HttpUrlConnection Server HttpContext HttpRequest HttpEntity HttpClient Server HttpResponse HttpEntity
  • 30. HttpUrlConnection HttpUrlConnection Server … HttpUrlConnection App
  • 31. HttpUrlConnection HttpUrlConnection Server … HttpUrlConnection App HttpContext HttpRequest HttpEntity HttpClient Server HttpResponse HttpEntity App
  • 32. Потокобезопасность 1 2 HttpUrlConnection Thread N
  • 33. Потокобезопасность 1 2 HttpUrlConnection Thread N
  • 34. Потокобезопасность HttpClient 1 2 Thread N
  • 35. Потокобезопасность HttpClient 1 2 ThreadSafeClientConnManager Thread N 1 connection 1 ... connection N 2 connection 2
  • 36. Потокобезопасность static { ... HttpParams params = new BasicHttpParams(); ConnManagerParams.setMaxTotalConnections(params, 10);
  • 37. Потокобезопасность static { ... HttpParams params = new BasicHttpParams(); ConnManagerParams.setMaxTotalConnections(params, 10); ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRoute() { @Override public int getMaxForRoute(HttpRoute route) { return 5; } });
  • 38. Потокобезопасность static { ... HttpParams params = new BasicHttpParams(); ConnManagerParams.setMaxTotalConnections(params, 10); ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRoute() { @Override public int getMaxForRoute(HttpRoute route) { return 5; } }); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); }
  • 39. Потокобезопасность static { ... HttpParams params = new BasicHttpParams(); ConnManagerParams.setMaxTotalConnections(params, 10); ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRoute() { @Override public int getMaxForRoute(HttpRoute route) { return 5; } }); ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); httpClient = new DefaultHttpClient(cm, params); }
  • 40. Application request request ... request request Server
  • 41. Application request request ... request request TCP TCP TCP TCP Server
  • 42. Application request request ... request request TCP + TCP …+… TCP + TCP = traffic Server
  • 44. Keep-alive cоединение Application request request ... request request TCP Server
  • 45. Keep-alive cоединение Application request request ... request request TCP + …+… + = traffic Server
  • 46. Номер Время(ms) запроса KeepAlive = false 1 2098 2 2157 3 2037 4 2096 5 1944 6 2055 7 1865 8 2119 9 1986 10 1965 ≈2032,2
  • 47. Номер Время(ms) Время(ms) запроса KeepAlive = false KeepAlive = true 1 2098 2023 2 2157 1604 3 2037 1698 4 2096 1774 5 1944 1173 6 2055 1573 7 1865 1683 8 2119 1670 9 1986 1666 10 1965 1541 ≈2032,2 ≈1700,5
  • 48. Номер Время(ms) Время(ms) запроса KeepAlive = false KeepAlive = true 1 2098 2023 2 2157 1604 3 2037 1698 4 2096 1774 На 16,2% быстрее! 5 1944 1173 6 2055 1573 7 1865 1683 8 2119 1670 9 1986 1666 10 1965 1541 ≈2032,2 ≈1700,5
  • 50. Keep Alive Duration 𝐭 App 𝐭 − 𝐭𝐢𝐦𝐞
  • 51. Keep Alive Duration request1 𝐭 App 𝐭 − 𝐭𝐢𝐦𝐞
  • 52. Keep Alive Duration request1 TCP 𝐭 App Server 𝐭 − 𝐭𝐢𝐦𝐞
  • 53. Keep Alive Duration request1 request2 TCP 𝐭 App Server 𝐭 − 𝐭𝐢𝐦𝐞
  • 54. Keep Alive Duration request1 request2 TCP request3 𝐭 App Server 𝐭 − 𝐭𝐢𝐦𝐞
  • 55. Keep Alive Duration request1 request2 TCP request3 𝐭 App Server request4 𝐭 − 𝐭𝐢𝐦𝐞
  • 56. Keep Alive Duration request1 request2 TCP request3 𝐭 App Server 𝐭𝟑> 𝐝 request4 𝐭 − 𝐭𝐢𝐦𝐞 𝐝 − 𝐤𝐞𝐞𝐩 𝐚𝐥𝐢𝐯𝐞 𝐝𝐮𝐫𝐚𝐭𝐢𝐨𝐧
  • 57. Keep Alive Duration request1 request2 TCP request3 𝐭 App Server 𝐭𝟑> 𝐝 request4 TCP 𝐭 − 𝐭𝐢𝐦𝐞 𝐝 − 𝐤𝐞𝐞𝐩 𝐚𝐥𝐢𝐯𝐞 𝐝𝐮𝐫𝐚𝐭𝐢𝐨𝐧
  • 58. Keep Alive Duration httpClient.setKeepAliveStrategy( new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(HttpResponse response, HttpContext context){ return KEEP_ALIVE_DURATION_MILLISECONDS; } });
  • 60. Keep Alive Duration if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO){ System.setProperty("http.keepAlive", "false"); }
  • 61. Keep Alive Duration if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO){ System.setProperty("http.keepAlive", "false"); } Hе поддается настройке!(≈5 секунд)
  • 62. try { ... InputStream is = connection.getInputStream(); // Вычитывайте все данные из InputStream’a is.close(); } catch (Exception e) { try { InputStream es = connection.getErrorStream(); // Вычитывайте все данные из InputStream’a es.close(); } catch (Exception ex) { ex.printStackTrace(); } }
  • 64. Гзипование траффика ... InputStream is = response.getEntity().getContent(); Header contentEncoding = response.getFirstHeader("Content-Encoding");
  • 65. Гзипование траффика ... InputStream is = response.getEntity().getContent(); Header contentEncoding = response.getFirstHeader("Content-Encoding"); if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip"))
  • 66. Гзипование траффика ... InputStream is = response.getEntity().getContent(); Header contentEncoding = response.getFirstHeader("Content-Encoding"); if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) { is = new GZIPInputStream(is); } ...
  • 67. Гзипование траффика ... InputStream is = connection.getInputStream(); String contentEncoding = connection.getContentEncoding(); if ("gzip".equalsIgnoreCase(contentEncoding)) { is = new GZIPInputStream(connection.getInputStream()); } ...
  • 69. Гзипование траффика Не полагайтесь на Content-Length!
  • 71. Управление куками Set-Cookie: name=value; expires=date; path=/; domain=.example.com
  • 72. Управление куками ... CookieStore cs = getHttpClient().getCookieStore(); BasicClientCookie c = new BasicClientCookie("Mpop", cookie); c.setDomain(".mail.ru"); cs.addCookie(c); ...
  • 73. Управление куками ... String cookieHeader = session.getCookieHeader(); сonnection.setRequestProperty("Cookie", cookieHeader); ...
  • 74. Установка куки в WebView Application
  • 75. Установка куки в WebView Application Browser WebView WebView
  • 76. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); WebView WebView
  • 77. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); WebView WebView
  • 78. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setCookie("mail.ru",cookie); WebView WebView
  • 79. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setCookie("mail.ru",cookie); WebView //for API level >= 15 CookieManager.getInstance().setCookie(".mail.ru",cookie); WebView
  • 80. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setCookie("mail.ru",cookie); WebView //for API level >= 15 CookieManager.getInstance().setCookie(".mail.ru",cookie) CookieSyncManager.getInstance().sync(); WebView
  • 81. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setCookie("mail.ru",cookie); WebView cookie //for API level >= 15 CookieManager.getInstance().setCookie(".mail.ru",cookie) CookieSyncManager.getInstance().sync(); WebView cookie
  • 82. Установка куки в WebView Application Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setCookie("mail.ru",cookie); WebView cookie //for API level >= 15 CookieManager.getInstance().setCookie(".mail.ru",cookie) CookieSyncManager.getInstance().sync(); WebView cookie
  • 86. Защищенное соединение (https) request Application Server CA Signs certificate
  • 87. Защищенное соединение (https) request Application Server Private key Certificate Public key CA Signs certificate
  • 88. Защищенное соединение (https) request Application Server Private key Certificate Public key Checks certificate CA Signs certificate
  • 89. Защищенное соединение (https) request Application Server Private key Certificate Public key Random symmetric key Checks certificate CA Signs certificate
  • 90. Защищенное соединение (https) request Application Server Private key Certificate Public key Random symmetric key Data transferring Checks certificate CA Signs certificate
  • 91. Варианты реализации https 1. KeyChain API на платформах >= 4.0
  • 92. Варианты реализации https 1. KeyChain API на платформах >= 4.0 2. На платформах < 4.0 надо создавать локальное хранилище ключей
  • 93. Варианты реализации https 1. KeyChain API на платформах >= 4.0 2. На платформах < 4.0 надо создавать локальное хранилище ключей 3. Доверять всем сертификатам
  • 94. Https на платформа < 4.0 ... TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); KeyStore keyStore = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(mykeystore); keyStore.load(in, "mysecret".toCharArray()); in.close(); tmf.init(keyStore); SSLContext sslc = SSLContext.getInstance("TLS"); sslc.init(null, tmf.getTrustManagers(),new SecureRandom()); ...
  • 95. Https на платформа < 4.0 private SSLSocketFactory createSslSocketFactory() { SSLSocketFactory sf = null; try { KeyStore keyStore = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(mykeystore); keyStore.load(in, "mysecret".toCharArray()); in.close(); sf = new SSLSocketFactory(keyStore); sf.setHostnameVerifier(STRICT_HOSTNAME_VERIFIER); } catch (Exception e) { e.printStackTrace(); } return sf; }
  • 96. Доверять всем сертификатам private class DummyHostnameVerifier implements HostnameVerifier{ @Override public boolean verify(String hostname, SSLSession session) { return true; } }
  • 97. Доверять всем сертификатам private class DummyTrustManager implements X509TrustManager{ @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { //empty } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { //empty } ... }
  • 98. Полезные инструменты 1. StrictMode 2. ConnectivityManager 3. DDMS Network Traffic Tool 4. Rest-client 5. Wireshark
  • 99. Полезные инструменты 1. StrictMode 2. ConnectivityManager 3. DDMS Network Traffic Tool 4. Rest-client 5. Wireshark
  • 100. Полезные инструменты 1. StrictMode 2. ConnectivityManager 3. DDMS Network Traffic Tool 4. Rest-client 5. Wireshark
  • 101. Полезные инструменты 1. StrictMode 2. ConnectivityManager 3. DDMS Network Traffic Tool 4. Rest-client 5. Wireshark
  • 102. Полезные инструменты 1. StrictMode 2. ConnectivityManager 3. DDMS Network Traffic Tool 4. Rest-client 5. Wireshark
  • 103. Полезные инструменты 1. StrictMode 2. ConnectivityManager 3. DDMS Network Traffic Tool 4. Rest-client 5. Wireshark
  • 104. Полезные ссылки 1. KeyChain API – http://goo.gl/ICijf 2. Создание локального хранилища ключей – http://goo.gl/5Surx 3. Keep Alive - http://goo.gl/9cdlz 4. Минимизация расхода батареи - http://goo.gl/DML0m 5. Выполнение сетевых операций - http://goo.gl/GIVIs
  • 105.
  • 106. А л е к с а н д р З а це п и н разработчик, Мобильная почта/Почта a l e x a n d e r. z a t s e p i n @ m a i l . r u