Zacepin
Upcoming SlideShare
Loading in...5
×
 

Zacepin

on

  • 621 views

 

Statistics

Views

Total Views
621
Views on SlideShare
472
Embed Views
149

Actions

Likes
0
Downloads
2
Comments
0

1 Embed 149

http://techforum.mail.ru 149

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Zacepin Zacepin Presentation Transcript

  • А л е к с а н д р З а це п и нразработчик, Мобильная почта/Почта 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 000700 000600 000500 000400 000 Приложения300 000200 000100 000 0 2009 2010 2011 2012
  • Более 800000 приложений
  • Server
  • Сокеты ServerClient ServerSocket Socket
  • Частые опросы (Polling) Server
  • Длинные опросы (Long-Polling) Server
  • Пуш-нотификации System Long-polling GCM subscribes regIdApp 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 HttpEntityHttpClient 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 HttpEntityHttpClient Server HttpResponse HttpEntity
  • HttpUrlConnectionHttpUrlConnection Server …HttpUrlConnection App
  • HttpUrlConnection HttpUrlConnection Server … HttpUrlConnection App HttpContext HttpRequest HttpEntityHttpClient 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);}
  • Applicationrequest request ... request request Server
  • Applicationrequest request ... request request TCP TCP TCP TCP Server
  • Applicationrequest request ... request request TCP + TCP …+… TCP + TCP = traffic Server
  • Keep-alive cоединение
  • Keep-alive cоединение Applicationrequest request ... request request TCP Server
  • Keep-alive cоединение Applicationrequest 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 DurationhttpClient.setKeepAliveStrategy( new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(HttpResponse response, HttpContext context){ return KEEP_ALIVE_DURATION_MILLISECONDS; } });
  • Keep Alive Duration
  • Keep Alive Durationif (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO){ System.setProperty("http.keepAlive", "false");}
  • Keep Alive Durationif (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);...
  • Установка куки в WebViewApplication
  • Установка куки в WebViewApplication Browser WebView WebView
  • Установка куки в WebViewApplication Browser CookieSyncManager.createInstance(context); WebView WebView
  • Установка куки в WebViewApplication Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); WebView WebView
  • Установка куки в WebViewApplication Browser CookieSyncManager.createInstance(context); CookieManager.getInstance().setAcceptCookie(true); CookieManager.getInstance().setCookie("mail.ru",cookie); WebView WebView
  • Установка куки в WebViewApplication 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
  • Установка куки в WebViewApplication 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
  • Установка куки в WebViewApplication 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
  • Установка куки в WebViewApplication 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) requestApplication Server CA Signs certificate
  • Защищенное соединение (https) requestApplication Server Private key Certificate Public key CA Signs certificate
  • Защищенное соединение (https) requestApplication Server Private key Certificate Public keyChecks certificate CA Signs certificate
  • Защищенное соединение (https) requestApplication Server Private key Certificate Public key Random symmetric keyChecks certificate CA Signs certificate
  • Защищенное соединение (https) requestApplication Server Private key Certificate Public key Random symmetric key Data transferringChecks certificate CA Signs certificate
  • Варианты реализации https1. KeyChain API на платформах >= 4.0
  • Варианты реализации https1. KeyChain API на платформах >= 4.02. На платформах < 4.0 надо создавать локальное хранилище ключей
  • Варианты реализации https1. KeyChain API на платформах >= 4.02. На платформах < 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.0private 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. StrictMode2. ConnectivityManager3. DDMS Network Traffic Tool4. Rest-client5. Wireshark
  • Полезные инструменты1. StrictMode2. ConnectivityManager3. DDMS Network Traffic Tool4. Rest-client5. Wireshark
  • Полезные инструменты1. StrictMode2. ConnectivityManager3. DDMS Network Traffic Tool4. Rest-client5. Wireshark
  • Полезные инструменты1. StrictMode2. ConnectivityManager3. DDMS Network Traffic Tool4. Rest-client5. Wireshark
  • Полезные инструменты1. StrictMode2. ConnectivityManager3. DDMS Network Traffic Tool4. Rest-client5. Wireshark
  • Полезные инструменты1. StrictMode2. ConnectivityManager3. DDMS Network Traffic Tool4. Rest-client5. Wireshark
  • Полезные ссылки1. KeyChain API – http://goo.gl/ICijf2. Создание локального хранилища ключей – http://goo.gl/5Surx3. Keep Alive - http://goo.gl/9cdlz4. Минимизация расхода батареи - http://goo.gl/DML0m5. Выполнение сетевых операций - 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