Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Мессенджер Наизнанку
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Max Sokolov
November 11, 2017
Programming
280
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Мессенджер Наизнанку
Max Sokolov
November 11, 2017
Transcript
83 slides
МЕССЕНДЖЕР НАИЗНАНКУ Максим Соколов, iOS @ Avito Ноябрь 2017 /
Mobius max_sokolov
None
ЧТО СЕГОДНЯ УМЕЕТ ЛЮБОЙ МЕССЕНДЖЕР? 3
ТЕКСТОВЫЕ СООБЩЕНИЯ НЕОТПРАВЛЕННЫЕ СООБЩЕНИЯ ЧЕРНЫЙ СПИСОК РЕАЛТАЙМ УВЕДОМЛЕНИЯ СТАТУСЫ СООБЩЕНИЙ
ОНЛАЙН СТАТУСЫ ШАРИНГ ФОТО ХРАНИЛИЩЕ СООБЩЕНИЙ ШАБЛОНЫ ОТВЕТОВ 4
Как спроектировать все так, чтобы потом не было больно? 5
Спойлер Несколько приложений - один мессенджер 6
План Проектирование API слоя взаимодействия с сервером Проектирование сервисного
слоя Трюки и советы 7
План Проектирование API слоя взаимодействия с сервером Проектирование сервисного
слоя Трюки и советы 8
Что такое API слой? Все что умеет делать Мессенджер, но
это еще не бизнес-логика. 9
RESPONSE SERIALIZER REQUEST SERIALIZER MESSENGER CLIENT NETWORK TRANSPORT 10
RESPONSE SERIALIZER REQUEST SERIALIZER MESSENGER CLIENT NETWORK TRANSPORT 11
Сетевой транспорт TCP Socket Web Socket HTTP (Polling / Long
Polling) ? 12
Задача В приложении нужен чат, никакого своего бекенда пока нет.
13
Сетевой транспорт TCP Socket Web Socket HTTP (Polling / Long
Polling) BaaS (Backend as a Service) 14
1 x App Середина 2015 BaaS Эволюция Мессенджера 15
“APIs for developers building secure realtime Mobile, Web, and IoT
Applications.” 16
Отправить сообщение Подписаться на новые сообщения Получить историю переписки PROFIT!
Backend as a Service 17
Не все сценарии можно реализовать (статусы доставки / прочтения,
черный список)* Нет контроля над перепиской (пре-обработка / спам)* Минусы Backend as a Service 18
Забавный факт Мы использовали parse.com и он закрылся :( На
BaaS надейся… 19
1 x App Backend в разработке 1 x App Конец
2015 HTTP Середина 2015 BaaS Эволюция Мессенджера 20
Задержки (Polling / Long polling - стратегия обновлений) Лишний трафик,
накладно делать некоторые сценарии* (http заголовки + хендшейки на соединение*) Лишние запросы (новых событий может не быть) HTTP Минусы 21
1 x App 1 x App Конец 2015 HTTP Середина
2015 BaaS 4 x App Конец 2016 Web Socket Backend в разработке Эволюция Мессенджера 22
Забавный факт Пришел веб-сокет, но приложение уже написано на BaaS
- мы не хотим переписывать… 23
Web Socket Нюансы работы с веб-сокетами 24
Протокол взаимодействия клиента и сервера 25
REQUEST-1 REQUEST-2 NOTIFICATION RESPONSE-1 RESPONSE-2 CLIENT-SERVER SOCKET CONNECTION 26
JSON-RPC 27
--> {"method": "sum", "params": [41, 1], "id": 1} <-- {"result":
42, "id": 1} 28
Дублирование сообщений в UI 29
SEND MSG NOTIF MSG-ID RESP MSG-ID DEVICE-1 SOCKET CONNECTION 30
DEVICE-2 SOCKET CONNECTION ОДИН ПОЛЬЗОВАТЕЛЬ - МНОГО СЕССИЙ NOTIF MSG-ID
Добавить в тело сообщения random id, назначенный на клиенте
Обрабатывать нотификации после того, как получены все ответы к запросам Решения Дублирование сообщений 31
Ping / Heartbeat Реконнекты Background Task Поддержка соединения 32
Web Socket Ack пакетов - подтверждение получения пакетов клиентом 33
ACKNOWLEDGED MSG-1 MSG-1 iOS ANDROID MSG-1 ACKNOWLEDGED MSG-1 MESSENGER SERVER
34
Web Socket & Polling? 35
Коды ошибок при разрыве (401 / рефреш токена) Очередь
на запросы к серверу (assert на превышение) Обработка ошибок 36
Итог Выбирайте сетевой транспорт под задачу (TCP Socket / Web
Socket / HTTP / BaaS) 37
REQUEST SERIALIZER RESPONSE SERIALIZER MESSENGER CLIENT NETWORK TRANSPORT 38
socket.isConnecting? 39
enum MessengerRequestState { case ready case delayed } 40
RESPONSE SERIALIZER REQUEST SERIALIZER MESSENGER CLIENT NETWORK TRANSPORT 41
MESSENGER API CORE Unbox Unbox Unbox In-house Mapper 42
Проблема Будут ли приложения определять свой контекст моделей данных? 43
final class MessengerResponseMapperImpl { func map<T: MessengerResponseMappable>( responseData: Data, completion:
@escaping (_ result: Result<T>) -> ()) { } } 44 protocol MessengerResponseMappable: class { static func map(_ dictionary: [String: String]) -> Self? } let dictionary = jsonParser.parse(data: responseData) let value = T.map(dictionary) completion(.value(value))
extension MessengerResponseMappable where Self: Unboxable { static func map(_ dictionary:
[String: String]) -> Self? { return try? unbox(dictionary: dictionary) } } 45
Итог Не завязывайте маппинг ответов сетевого слоя на конкретную реализацию
46
MESSENGER CLIENT RESPONSE SERIALIZER REQUEST SERIALIZER NETWORK TRANSPORT 47
open class MessengerClient { /* Inject: Network transport Request serializer
Response serializer */ func getChats<T: MessengerResponseMappable>( completion: @escaping (_ result: Result<[T]>) -> Void) { } } 48
messengerClient.getChats( completion: { (result: Result<[Chat]>) in } ) 49
messengerClient.getChats( completion: { (result: Result<[OtherChat]>) in } ) 50
MESSENGER CLIENT RESPONSE SERIALIZER REQUEST SERIALIZER NETWORK TRANSPORT MESSENGER API
CORE 51
Выносите слой работы с API в отдельный модуль (мы
используем Private CocoaPods) Вывод 52
План Проектирование API слоя взаимодействия с сервером Проектирование сервисного
слоя Трюки и советы 53
Легко тестировать Легко расширять Легко переиспользовать Легко композировать сервисы друг
с другом Сервисный слой 54
Легко тестировать Легко расширять Легко переиспользовать Легко композировать сервисы друг
с другом Сервисный слой 55
НОВОЕ СООБЩЕНИЕ В ЧАТЕ СТАТУС СООБЩЕНИЯ ЮЗЕР ОНЛАЙН ЧЕРНЫЙ СПИСОК
56
МИКРОСЕРВИСНАЯ АРХИТЕКТУРА 57
CHAT LIST SERVICE USERS ONLINE STATUS SERVICE MESSAGES STATUS SERVICE
NEW MESSAGE SERVICE BLACK LIST SERVICE DELETE CHAT SERVICE REACHABILITY SERVICE 58
FAVOR COMPOSITION 59
Как связать все вместе? 60
OBSERVER PATTERN Шаблон проектирования Наблюдатель 61
protocol UsersOnlineStatusObservable: class { func add( observer: AnyObject, onUsersOnlineStatusChange: @escaping
(([User]) -> ()) ) func remove(observer: AnyObject) } 62
protocol UsersOnlineStatusService: class { func startPollingOnlineStatuses() } 63
final class UsersOnlineStatusServiceImpl: UsersOnlineStatusService, UsersOnlineStatusObservable { } 64
// MARK: - state private var chats: [Chat] { }
func subscribeOnUpdates() { usersOnlineStatusServiceObservable.add( observer: self, onUsersOnlineStatusChange: { users in // update chats } ) } 65 didSet { notifyObservers() } newMessagesServiceObservable.add( observer: self, onNewMessage: { newMessage in // update chats } )
CHAT LIST SERVICE OBSERVABLE USERS ONLINE STATUS SERVICE MESSAGES STATUS
SERVICE NEW MESSAGE SERVICE BLACK LIST SERVICE DELETE CHAT SERVICE REACHABILITY SERVICE OBSERVABLE OBSERVABLE OBSERVABLE OBSERVABLE OBSERVABLE OBSERVABLE 66
ObserverList<T>.swift http://gist.github.com 67
Микросервисы - небольшие блоки, соединяющиеся в единую систему Консистентность -
все сервисы спроектированы одинаково Выводы 68
План Проектирование API слоя взаимодействия с сервером Проектирование сервисного
слоя Трюки и советы 69
onChatListChange -> [Chat] PRESENTER VIEW INTERACTOR CHAT LIST SERVICE …
[CellData] -> setViewData 70
onChatListChange -> [Chat] PRESENTER VIEW INTERACTOR CHAT LIST SERVICE …
[CellData] -> setViewData 71
Проблема Слишком частые обновления UI 72
DEBOUNCE THROTTLE SAMPLE 73 DELAY
Sample Operator Emit the most recent items emitted by an
Observable within periodic time intervals 74
TIME TIME SAMPLE ⏱ ⏱ 75
let sampler = Sampler(delay: 0.5) sampler.sample { // update ui
here... } 76
Sampler.swift http://gist.github.com 77
Проблема Обновление UI, если пользователь покинул экран 78
final class ChatListViewController: UIViewController { func processOnChatListUpdates(_ chats: [ChatViewData]) {
} } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) invokeClosuresHelper.setViewIsReady(true) } 79 invokeClosuresHelper.invokeOrDelayIfViewIsNotReady { // do ui updates... }
Проблема UITableView / UICollectionView Обновление элементов, поиск index path изменившихся
80
Diff алгоритм ITEM 3 ITEM 4 ITEM 2 ITEM 1
ITEM 5 ITEM 4 ITEM 6 ITEM 5 ITEM 2 ITEM 7 RELOADS INSERTS DELETES 81
Выбирайте инструмент под задачу Выносите логику работы c API в
отдельный модуль Закладывайте масштабируемость Общайтесь с коллегами из других платформ Выводы 82
/MAXSOKOLOV @MAX_SOKOLOV https://github.com/maxsokolov https://gist.github.com/maxsokolov https://twitter.com/max_sokolov Вопросы?
[email protected]
Примеры кода gist.github.com/maxsokolov
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
260
Secure Your Coding Agent Like It’s Malware (v1.5) 🇬🇧 @Code.talks 2026
richargh
0
120
Seven New Principles of Software Engineering
yegor256
0
480
Kawaiicon: Kubernetes, it's no longer cool, but let's secure it anyway!
barnbarn
0
130
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.5k
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
2.3k
Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜
umigishiaoi
0
160
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
180
Railsバージョンを4倍にした話
optim
0
1k
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
320
Vue.jsで作る空間解析アプリとCapacitorプラグインのData Bridge
hal_spidernight
1
170
オーケストレーション記述言語 Katari
yukikurage
0
250
Featured
See All Featured
Tell your own story through comics
letsgokoyo
1
1.1k
A Modern Web Designer's Workflow
chriscoyier
699
190k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
370
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
How Software Deployment tools have changed in the past 20 years
geshan
3
35k
Test your architecture with Archunit
thirion
2
2.5k
Believing is Seeing
oripsolob
1
280
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
Color Theory Basics | Prateek | Gurzu
gurzu
1
520
Chasing Engaging Ingredients in Design
codingconduct
0
390
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
740
The World Runs on Bad Software
bkeepers
PRO
72
12k