От около година съм инженер в ApeeScape и работя по същия проект на WebRTC, откакто се присъединих към мрежата: Ондело , услуга, която свързва лекари и пациенти WebRTC . Помислете за Google+ Hangouts за здравеопазване.
( WebRTC е технология, която позволява комуникация в реално време чрез уеб браузър. Най-добрият пример отново е Google+ Hangouts: без външен аплет получавате видео чат в реално време. Има добър запис тук . )
Когато за първи път се присъединих към Ondello, бях нает като Старши разработчик на Ruby on Rails , възложена на изграждане на услуга нагоре от нулата. В наши дни сме екип от множество разработчици, работещи по доста голяма, сложна система.
С тази публикация бих искал да споделя историята зад Ondello. По-конкретно, бих искал да говоря за:
Както споменах по-рано, Ondello е всичко за платформата WebRTC. Но само Chrome, Firefox и Opera понастоящем поддържа WebRTC разговори без използването на приставка. Целта ни беше да поддържаме всички браузъри (Safari и Internet Explorer са очевидните пропуски в горния списък) и като такива трябваше да използваме приставка, която беше сравнително млада.
Когато започнах да работя с приставката, нещата вървяха гладко, тъй като имаха много добра документация и официални уроци и ръководства за WebRTC. Но тъй като продуктът ни се разширяваше, а изискванията ни се усложняваха, нещата се обърнаха към по-лошо. Това не беше толкова просто, колкото отстраняването на проблеми с Rails.
Тъй като WebRTC е малко по-нова технология и по-специално този плъгин е доста нов (все още се кани само с разумно голяма такса за използване), те не са привлекли много разработчици, камо ли разработчици на WebRTC Rails да пишат ръководства и уроци за хора като мен. Тези фактори критично увреждат общността на разработчиците около нея, която по същество не съществува.
Никога не съм смятал това за основен проблем - докато не го пропусна. За повечето платформи и технологии на приложенията общите случаи са лесни за справяне, но карат нещата да работят по много специфичен начин при много конкретен срок - което изисква интимно познаване на технологията или достъп до колеги разработчици.
Представете си програмирането в свят без StackOverflow - колко лошо ще бъде възпрепятствана вашата производителност?
Разбира се, имахме известен достъп до разработчиците на приставката, които бяха толкова полезни, колкото можех да очаквам. Това облекчи някои от проблемите, но не беше същото като просто Googling „WebRTC плъгин foo не работи поради лента“ .
Всеки софтуер там има грешки.
Но в случая с тези нови технологии WebRTC беше трудно да се разбере кой е бащата и кое е детето. С други думи: когато открихме неуспешен тестов случай или очевидна грешка, не беше ясно дали ние са били виновни или ако е имало грешка в кодовата база, която сме използвали.
Това, което може да бъде лесно за търсене в Google за повечето технологии, се превърна в огромна верига за електронна поща, последвана от прегледи на кодове и, в някои случаи, конференция с разработчиците на WebRTC.
По този въпрос бих казал, че имаме приблизително 50-50 грешки поради екипа за разработчици на плъгина и нашите собствени.
Друго следствие от относителното детство на тази приставка WebRTC е скорост на актуализация . По-младият софтуер се актуализира по-често и тези актуализации често се провалят. С приставката не можахме да продължим да използваме по-стари версии (като телекомуникационна технология всички потребители трябваше да използват една и съща версия, за да комуникират помежду си), така че всяко издание изискваше рефакторинг.
Тези актуализации бяха болезнени. Често имахме стабилен код, който трябваше да бъде пренаписан изцяло, за да се синхронизира с последните промени. В някои случаи тестовете биха се провалили без обяснение - и ако няма общност, къде да се обърнете за помощ?
В някои случаи тестовете биха се провалили без обяснение - и ако няма общност, къде да се обърнете за помощ?С нарастването на нашия продукт повечето от нашите клиенти започнаха да питат за мобилна поддръжка.
как да се създаде прототип
Ако библиотеката WebRTC JavaScript беше трудна, тогава библиотеката на Android беше двойно по-голяма. Отне ми два дни само за съставяне на примерното приложение и повече от пет часа само за да разбера как работи - целият процес даде на думата ‘болезнено’ ново значение.
След 10 часа неуспешна компилация имах психически срив и плаках малко. Събирайки се, успях да накарам нещата да работят след още два часа. Pff — и Обама казва, че трябва да правите свои собствени видео игри .
Библиотеката на WebRTC iOS беше по-лесна и екипът на разработчиците явно беше отделил повече време за нея. Успяхме да го пуснем в действие само за няколко часа.
Преминавайки отвъд приставката WebRTC, нашата кодова база на JavaScript ме научи много на сложността. Тъй като повечето WebRTC рамки се базират на JavaScript за конфигуриране (напр. Plivo’s web framework за VoIP ), това беше единственият език, който използвах през първите три месеца в Ondello.
И тъй като нашата кодова база растеше, тя естествено ставаше все по-малко управляема. Имахме дълбоко вложени обратни извиквания, лоша модуларизация и други - това беше първият опит на стартиращо приложение в WebRTC JavaScript приложение и, както може да се очаква, беше малко разхвърлян.
В крайна сметка преминахме към CoffeeScript . Това намали размер на нашата кодова база и увеличи нейната четливост значително, но не беше достатъчно за справяне с истинските ни сложни проблеми.
След това открихме PubSub , прекрасна библиотека за публикуване / абониране за JavaScript, която не мога да препоръчам достатъчно силно. Този малък човек ни помогна да отделим значителна част от нашата логика на JavaScript; процесът ни на рефакторинг се обърна към най-доброто с откритието си.
Защо PubSub беше толкова полезен? WebRTC е присъщо свързан с медиите и връзките и по този начин е пълен със събития. С PubSub можем лесно да наблюдаваме определени събития на високо ниво на абстракция. Това беше чудесно решение и чудесен пример за неразрешаване на разрешения проблем: когато имате добре написани, добре документирани решения с отворен код (или дори патентовани), които ще опростят вашата кодова база и ще ускорят развитието, използвай ги .
За да бъдем по-конкретни: Без PubSub, всеки път, когато камерата на потребителя изгасне, трябваше да актуализираме три квадратчета, които представляват състоянието на камерата:
camera_went_off = function() { $(''#checkbox1').removeAttr('checked'); $(''#checkbox2').removeAttr('checked'); $(''#checkbox3').removeAttr('checked'); }
С PubSub можех просто да задействам събитието „camera_went_off“ и да накарам и трите квадратчета да го слушат. Освен това, ако някой щракне върху едно от тези квадратчета, той може също да публикува това събитие, за да уведоми останалите квадратчета, за да се актуализират.
Както споменахме по-рано, използвахме приставка WebRTC, за да поддържаме по-широк набор от браузъри. Но този плъгин трябва да се зарежда всеки път, когато потребителят зарежда нова страница. Това може да има ужасни последици за производителността, плавността и т.н.
Единственият отговор беше да поддържате приставката заредена веднага щом потребителят влезе в сайта и да гарантира, че потребителят не е презаредил или не е въвел друга уеб страница. Това звучи невъзможно. Но всъщност това може да бъде постигнато с a приложение на една страница (СПА).
В този момент, AngularJS влезе в игра.
С Angular се преместихме в SPA. Когато потребител влезе в сайта, той зареди приставката веднъж - и само веднъж. Повишаването на ефективността беше моментално.Angular ни позволи да изградим SPA, което от своя страна ни позволи да заредим плъгина веднъж (когато потребителят влезе в системата) и само веднъж. Тогава всяко обаждане, направено от потребителя, ще бъде почти мигновено, тъй като приставката вече ще бъде заредена. Това отне много работа, но се отплати - печалбите от производителността бяха мигновени.
Angular също подобри нашия JavaScript код като цяло чрез налагане на MVC структура. Докато повечето от JavaScript трябваше да бъдат пренаписани, за да се съчетаят с ъгловия модел, това беше полезно начинание.
Срещнахме подобни проблеми със сложността с нашия CSS: модуларизацията не беше съвсем правилна, имахме припокриващи се стилове и т.н. Не би било честно да се каже, че нашата кодова база беше масивна в сравнение с много други системи, но като малък екип, работещ при стартиране: 1) времето е от съществено значение и 2) организацията е от ключово значение.
Ключът към намаляването на сложността с нашия CSS беше използването на Sass и Компас .
Първият път, когато използвах Sass, не бях много доволен от него. Но днес не мога да си представя живота без него. Накратко, Sass е CSS език за разширение което ви позволява да пишете таблици със стилове в синтаксиса на Sass и да ги компилирате до CSS.
Sass изобилие от невероятна функционалност: променливи , директиви за контрол , SassScript като цяло и др. Но това, което наистина ме продаде на него и това, което наистина направи огромна разлика за Ondello, беше Sass’s вложени правила .
Те са най-добре илюстрирани с пример. Без Sass може да имам CSS код, който изглежда така:
.container_div { float: left; height: 10px; width: 20px; } .container_div a { margin-left: 15px; }
Но с Sass това може да бъде опростено до:
.container_div float: left height: 10px width: 20px a margin-left: 15px
В този тривиален пример съм запазил само няколко реда. Но представете си, ако имам някакъв CSS код на индустриално ниво, който може да бъде изразен със Sass като:
.admin-section-menu width: 270px float: left margin-right: 8px padding-top: 30px ul padding-right: 10px li width: 230px a float: left text-align: right letter-spacing: 1px font-size: 20px color: #666 width: 220px margin-bottom: 20px &.active a width: 230px color: #52672d &:after content: '25b8' display: inline position: relative left: 10px
Компас е CSS рамка за създаване, която се основава на Sass и наистина ни помогна с дизайна на интерфейса. Използвахме Compass, за да ни помогне да направим спрайтове - има страхотен урок тук , ако се интересувате.
С Compass бихме могли да ускорим създаването на сложни бутони. Това беше толкова просто, колкото поставянето на състоянието на изображението на бутоните в папка, в който момент Compass ще генерира спрайт, за да ги съдържа.
В този пример Compass чете всички файлове в бутони_администрация папка и ги поставете в един спрайт файл.
@import 'administration_buttons/*.png' @include all-administration_buttons-sprites .add-user-button width : 37px height : 37px cursor : pointer float: right @include administration_buttons-sprite(add_user) &:hover @include administration_buttons-sprite(add_user_rollover)
Чрез @include administration_buttons-sprite(add_user)
команда, добавям файла add_user.png като фоново изображение за add-user-button
клас.
С Compass трябваше само да сложа няколко изображения в папка.
Без Компас би трябвало да:
За разработчик като мен, който не е особено Photoshop-разбирам , това спести огромно време. И отново, времето е от решаващо значение на този етап.
След няколко месеца JavaScript и CSS, най-накрая преминахме към нашия Ruby on Rails back-end.
Моделите на релсите са чудесни за опростяване на проектите, тъй като има много ясно разделяне със структурата на MVC. Ако вашата система започне да расте, само моделите на Rails може да са недостатъчни. Вместо това трябва да помислите за нови начини на високо ниво за решаване на вашите проблеми - нови средства за абстракция.
Всички сме изучавали кодови модели, идеологии, уроци, ръководства и т.н. Всички знаем за разделянето на вашата логика на класове и класовете ви на функции и всичко това. Но рядко ни учат решения . Никога не съм чел книга за това и никога не съм виждал курс по него.
След като работих с Rails известно време, започнах да виждам, че проблемът не е в кода, а в решението за решаване на проблема на клиента.
Обратно към WebRTC за Ondello: като конкретен пример имахме много проста пощенска система, изградена върху Rails. От известно време това работи добре за нас. Но в крайна сметка се нуждаехме от специален вид имейл за всеки клиент. С течение на времето промените между имейлите започнаха да стават все по-големи и по-големи - в крайна сметка всеки клиент се нуждаеше от напълно различен имейл.
Ако вашата система започне да расте, само моделите на Rails може да са недостатъчни. Вместо това трябва да помислите за нови начини на високо ниво за решаване на вашите проблеми - нови средства за абстракция.Започнах да виждам, че с нарастването на моята кодова база този вид функционалност ще има огромно влияние върху цялата ми WebRTC рамка и пощенска система. Тогава решихме да създадем отделен проект единствено за пощенската система, отговорен за обработката на всякакъв вид съобщения. Основният проект просто ще изпрати (чрез ПОЧИВКА ) някои параметри и идентификатор на клиента. След това пощенската система ще се погрижи за сглобяването и изпращането на имейли.
Този подход, този на разделянето на проекта на различни проекти, беше полезен при разработването на Ondello. Той позволи на основния проект да остане опростен и без излишни отговорности.
Този вид решаване на проблеми е това, което аз наричам a подход за решения . Смятам, че е от съществено значение за разработването на сложни приложения.
Без значение дали сте разработчик на Ruby, Java или PHP, когато става въпрос за уеб разработка, има толкова много рамки и технологии, толкова много различни инструменти, които можете или трябва да използвате, за да накарате вашата система да работи, че в очите ми, трудно е да се види някой като програмист „Ruby“ или програмист „Java“.
Що се отнася до големите системи, трябва да проектирате добре изработени решения, които да отговорят на нуждите на вашите клиенти - и които не винаги ще се впишат във вашите любими технологии или дори технологиите, с които се чувствате удобно. Общата тема в развитието на Ondello беше, че трябваше да бъда гъвкав и пъргав, използвайки най-подходящите технологии, налични във всеки един момент, независимо от моите предпочитания.
При разработването на Ondello си спомних, че преди всичко трябва да сме инженери, да решаваме проблеми с възможно най-добрите инструменти и да свършим работата ефективно, мащабируемо и практично.