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
Other Decks in Programming
See All in Programming
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
110
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
140
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
220
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
2
700
ジョジョの世界をXRで再現する
mofurune
0
160
最近”作らせてる” ローカルAIアプリの話
akit37
0
470
AmebaブログはKMPから卒業します
kmars0605
0
190
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
190
AWSに止められる覚悟してますか?
morizo_1984
2
540
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
600
sbt 2.0: takeoff
eed3si9n
0
160
Featured
See All Featured
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Utilizing Notion as your number one productivity tool
mfonobong
4
620
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
580
Building the Perfect Custom Keyboard
takai
2
910
A Soul's Torment
seathinner
8
3.8k
So, you think you're a good person
axbom
PRO
2
2.2k
Become a Pro
speakerdeck
PRO
31
6.3k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
630
Writing Fast Ruby
sferik
630
63k
Transcript
МЕССЕНДЖЕР НАИЗНАНКУ Максим Соколов, 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