Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

Určite mnohí z vás, rovnako ako ja, mali nápad urobiť niečo jedinečné. V tomto článku popíšem technické problémy a riešenia, ktorým som musel pri vývoji PBX čeliť. Snáď to niekomu pomôže rozhodnúť sa pre svoj vlastný nápad a niekomu ísť po zabehnutých koľajach, pretože aj ja som ťažil zo skúseností priekopníkov.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

Idea a kľúčové požiadavky

A všetko to začalo jednoducho láskou hviezdička (rámec pre aplikácie komunikácie budov), automatizácia telefonovania a inštalácií free pbx (webové rozhranie pre hviezdička). Ak by potreby spoločnosti boli bez špecifík a spadali do možností free pbx - všetko je skvelé. Celá inštalácia prebehla do XNUMX hodín, spoločnosť dostala nakonfigurovanú PBX, užívateľsky prívetivé rozhranie a krátke zaškolenie plus podporu na želanie.

Ale najzaujímavejšie úlohy boli neštandardné a potom to už nebolo také rozprávkové. hviezdička dokáže veľa, no na udržanie funkčného webového rozhrania bolo potrebné stráviť mnohonásobne viac času. Takže malý detail môže trvať oveľa dlhšie ako inštalácia zvyšku PBX. A nejde o to, že napísanie webového rozhrania trvá dlho, ale ide skôr o architektonické prvky free pbx. Prístupy a metódy architektúry free pbx bol rozvrhnutý v čase php4 a v tom momente už existoval php5.6, na ktorom sa dalo všetko zjednodušiť a pohodlnejšie.

Poslednou kvapkou boli grafické číselníky vo forme diagramu. Keď som sa pokúsil postaviť niečo také pre free pbx, uvedomil som si, že to budem musieť výrazne prepísať a bude jednoduchšie postaviť niečo nové.

Kľúčové požiadavky boli:

  • jednoduché nastavenie, intuitívne prístupné aj začínajúcemu správcovi. Spoločnosti teda nevyžadujú údržbu PBX z našej strany,
  • jednoduchá modifikácia tak, aby úlohy boli vyriešené v primeranom čase,
  • jednoduchá integrácia s PBX. U free pbx neexistovalo API na zmenu nastavení, t.j. Nemôžete napríklad vytvárať skupiny alebo hlasové menu z aplikácie tretej strany, iba pomocou samotného API hviezdička,
  • opensource – pre programátorov je to mimoriadne dôležité pri úpravách pre klienta.

Myšlienkou rýchlejšieho vývoja bolo, aby všetka funkcionalita pozostávala z modulov vo forme objektov. Všetky objekty museli mať spoločnú rodičovskú triedu, čo znamená, že názvy všetkých hlavných funkcií sú už známe, a preto už existujú predvolené implementácie. Objekty vám umožnia dramaticky znížiť počet argumentov vo forme asociatívnych polí s kľúčmi reťazca, ktoré zistíte v free pbx Bolo to možné skúmaním celej funkcie a vnorených funkcií. V prípade objektov banálne automatické dopĺňanie ukáže všetky vlastnosti a vo všeobecnosti mnohonásobne zjednoduší život. Navyše, dedenie a redefinícia už riešia mnohé problémy s úpravami.

Ďalšia vec, ktorá spomalila čas prepracovania a ktorej sa oplatilo vyhnúť, bola duplicita. Ak existuje modul zodpovedný za vytáčanie zamestnanca, potom by ho mali používať všetky ostatné moduly, ktoré potrebujú poslať hovor zamestnancovi, a nie vytvárať svoje vlastné kópie. Ak teda potrebujete niečo zmeniť, budete sa musieť zmeniť iba na jednom mieste a hľadanie „ako to funguje“ by sa malo vykonávať na jednom mieste, a nie hľadať počas celého projektu.

Prvá verzia a prvé chyby

Prvý prototyp bol hotový do roka. Celá PBX bola podľa plánu modulárna a moduly mohli nielen pridať novú funkcionalitu pre spracovanie hovorov, ale aj zmeniť samotné webové rozhranie.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php
Áno, myšlienka vybudovať dialplán vo forme takejto schémy nie je moja, ale je veľmi pohodlná a urobil som to isté pre hviezdička.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

Napísaním modulu už programátori mohli:

  • vytvoriť si vlastnú funkcionalitu pre spracovanie hovorov, ktorú je možné umiestniť do diagramu, ako aj do menu prvkov vľavo,
  • vytvorte si vlastné stránky pre webové rozhranie a pridajte svoje šablóny na existujúce stránky (ak to vývojár stránky zabezpečil),
  • pridajte svoje nastavenia na hlavnú kartu nastavení alebo si vytvorte vlastnú kartu nastavení,
  • programátor môže dediť z existujúceho modulu, zmeniť časť funkcionality a zaregistrovať ju pod novým názvom alebo nahradiť pôvodný modul.

Takto si napríklad môžete vytvoriť svoje vlastné hlasové menu:

......
class CPBX_MYIVR extends CPBX_IVR
{
 function __construct()
 {
 parent::__construct();
 $this->_module = "myivr";
 }
}
.....
$myIvrModule = new CPBX_MYIVR();
CPBXEngine::getInstance()->registerModule($myIvrModule,__DIR__); //Зарегистрировать новый модуль
CPBXEngine::getInstance()->registerModuleExtension($myIvrModule,'ivr',__DIR__); //Подменить существующий модуль

Prvé komplexné realizácie priniesli prvú hrdosť a prvé sklamania. Bol som rád, že to funguje, že sa mi už podarilo zreprodukovať hlavné črty free pbx. Bol som rád, že sa ľuďom myšlienka schémy páčila. Možností na zjednodušenie vývoja bolo ešte veľa, no už v tom čase sa niektoré úlohy uľahčovali.

Rozhranie API na zmenu konfigurácie PBX bolo sklamaním – výsledok vôbec nebol taký, aký sme chceli. Bral som rovnaký princíp ako v free pbx, kliknutím na tlačidlo Použiť sa celá konfigurácia znova vytvorí a moduly sa reštartujú.

Vyzerá to takto:

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php
*Dialplan je pravidlo (algoritmus), podľa ktorého sa hovor spracováva.

Ale s touto možnosťou nie je možné napísať normálne API na zmenu nastavení PBX. Po prvé, operácia aplikácie zmien na hviezdička príliš dlhé a náročné na zdroje.
Po druhé, nemôžete volať dve funkcie súčasne, pretože obaja vytvoria konfiguráciu.
Po tretie, použije všetky nastavenia vrátane tých, ktoré vykonal správca.

V tejto verzii, ako v Askozia, bolo možné vygenerovať konfiguráciu len zmenených modulov a reštartovať len potrebné moduly, ale to sú všetko polovičné opatrenia. Bolo potrebné zmeniť prístup.

Druhá verzia. Nos vytiahnutý chvost zaseknutý

Myšlienkou na vyriešenie problému nebolo znovu vytvoriť konfiguráciu a dialplan hviezdička, ale uložiť informácie do databázy a čítať z databázy priamo počas spracovania hovoru. hviezdička Už som vedel čítať konfigurácie z databázy, stačí zmeniť hodnotu v databáze a ďalší hovor bude spracovaný s prihliadnutím na zmeny a funkcia bola perfektná na čítanie parametrov dialplanu REALTIME_HASH.

Nakoniec nebolo potrebné ani reštartovať hviezdička pri zmene nastavení sa všetky nastavenia začali okamžite uplatňovať hviezdička.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

Jediné zmeny v dialplane sú pridanie čísel klapiek a rady. Boli to však malé bodové zmeny

exten=>101,1,GoSub(‘sub-callusers’,s,1(1)); - точечное изменение, добавляется/изменяется через ami

; sub-callusers – универсальная функция генерится при установке модуля.
[sub-callusers]
exten =>s,1,Noop()
exten =>s,n,Set(LOCAL(TOUSERID)=${ARG1})
exten =>s,n,ClearHash(TOUSERPARAM)
exten =>s,n,Set(HASH(TOUSERPARAM)=${REALTIME_HASH(rl_users,id,${LOCAL(TOUSERID)})})
exten =>s,n,GotoIf($["${HASH(TOUSERPARAM,id)}"=""]?return)
...

Linku v dialplane môžete jednoducho pridať alebo zmeniť pomocou Ami (ovládacie rozhranie hviezdička) a nevyžaduje sa reštart celého dialplanu.

Tým sa vyriešil problém s konfiguračným API. Môžete dokonca priamo prejsť do databázy a pridať novú skupinu alebo zmeniť napríklad čas vytáčania v poli „dialtime“ pre skupinu a ďalší hovor by už trval stanovený čas (Toto nie je odporúčanie pre pretože niektoré operácie API vyžadujú Ami hovory).

Prvé ťažké realizácie opäť priniesli prvú hrdosť a sklamanie. Bol som rád, že to funguje. Databáza sa stala kritickým článkom, zvýšila sa závislosť na disku, bolo viac rizík, ale všetko fungovalo stabilne a bez problémov. A čo je najdôležitejšie, teraz všetko, čo sa dalo urobiť cez webové rozhranie, sa dalo urobiť cez API a použili sa rovnaké metódy. Webové rozhranie sa navyše zbavilo tlačidla „použiť nastavenia na PBX“, na ktoré správcovia často zabúdali.

Sklamaním bolo, že vývoj sa skomplikoval. Od prvej verzie jazyk PHP generoval dialplan v jazyku hviezdička a vyzerá to úplne nečitateľne, plus samotný jazyk hviezdička na písanie dialplanu je to mimoriadne primitívne.

Ako to vyzeralo:

$usersInitSection = $dialplan->createExtSection('usersinit-sub','s');
$usersInitSection
 ->add('',new Dialplanext_gotoif('$["${G_USERINIT}"="1"]','exit'))
 ->add('',new Dialplanext_set('G_USERINIT','1'))
 ->add('',new Dialplanext_gosub('1','s','sub-AddOnAnswerSub','usersconnected-sub'))
 ->add('',new Dialplanext_gosub('1','s','sub-AddOnPredoDialSub','usersinitondial-sub'))
 ->add('',new Dialplanext_set('LOCAL(TECH)','${CUT(CHANNEL(name),/,1)}'))
 ->add('',new Dialplanext_gotoif('$["${LOCAL(TECH)}"="SIP"]','sipdev'))
 ->add('',new Dialplanext_gotoif('$["${LOCAL(TECH)}"="PJSIP"]','pjsipdev'))

V druhej verzii sa dialplán stal univerzálnym, obsahoval všetky možné možnosti spracovania v závislosti od parametrov a jeho veľkosť sa výrazne zväčšila. To všetko značne spomalilo vývojový čas a už len pomyslenie, že ešte raz treba zasahovať do dialplanu, ma mrzelo.

Tretia verzia

Myšlienkou vyriešiť problém nebolo generovať hviezdička dialplan z php a použite FastAGI a napíšte všetky pravidlá spracovania v samotnom PHP. FastAGI umožňuje hviezdička, na spracovanie hovoru sa pripojte k zásuvke. Odtiaľ prijímajte príkazy a odosielajte výsledky. Logika dialplanu je teda už za hranicami hviezdička a môže byť napísaný v akomkoľvek jazyku, v mojom prípade v PHP.

Bolo tam veľa pokusov a omylov. Hlavným problémom bolo, že som už mal veľa tried/súborov. Vytvorenie objektov, ich inicializácia a vzájomná registrácia trvalo približne 1,5 sekundy a toto oneskorenie na jeden hovor nemožno ignorovať.

Inicializácia mala prebehnúť iba raz a preto hľadanie riešenia začalo napísaním služby v php pomocou Pthreads. Po týždni experimentovania bola táto možnosť odložená z dôvodu zložitosti fungovania tohto rozšírenia. Po mesiaci testovania som musel opustiť aj asynchrónne programovanie v PHP, potreboval som niečo jednoduché, známe každému PHP začiatočníkovi a mnohé rozšírenia pre PHP sú synchrónne.

Riešením bola naša vlastná viacvláknová služba v jazyku C, ktorá bola skompilovaná PHPLIB. Načíta všetky php súbory ATS, počká na inicializáciu všetkých modulov, pridá k sebe spätné volanie a keď je všetko pripravené, uloží to do vyrovnávacej pamäte. Pri dopyte podľa FastAGI vytvorí sa stream, reprodukuje sa v ňom kópia z cache všetkých tried a údajov a požiadavka sa odovzdá funkcii php.

Pri tomto riešení je čas od odoslania hovoru našej službe po prvý príkaz hviezdička klesol z 1,5s na 0,05s a tento čas mierne závisí od veľkosti projektu.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

V dôsledku toho sa výrazne skrátil čas na vývoj číselného plánu, čo môžem oceniť, pretože som musel prepísať celý číselný plán všetkých modulov v PHP. Po prvé, v php by už mali byť napísané metódy na získanie objektu z databázy, tie boli potrebné na zobrazenie vo webovom rozhraní a po druhé, a to je hlavné, konečne sa dá pohodlne pracovať s reťazcami s číslami a poľami s databázou a mnohými rozšíreniami PHP.

Na spracovanie dialplanu v triede modulu je potrebné implementovať funkciu dialplanDynamicCall a argument pbxCallRequest bude obsahovať objekt na interakciu hviezdička.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

Okrem toho bolo možné ladiť dialplan (php má xdebug a funguje pre našu službu), môžete sa pohybovať krok za krokom prezeraním hodnôt premenných.

Údaje o hovoroch

Akékoľvek analýzy a reporty vyžadujú správne zozbierané dáta a aj tento blok PBX prešiel od prvej až po tretiu verziu množstvom pokusov a omylov. Údaje o hovoroch sú často znakom. Jeden hovor = jedna nahrávka: kto volal, kto odpovedal, ako dlho hovorili. V zaujímavejších možnostiach je doplnková tabuľa označujúca, ktorý zo zamestnancov ústredne bol počas hovoru volaný. To všetko však pokrýva len časť potrieb.

Počiatočné požiadavky boli:

  • uložiť nielen komu PBX volala, ale aj kto odpovedal, pretože existujú odpočúvania a toto bude potrebné vziať do úvahy pri analýze hovorov,
  • čas pred spojením so zamestnancom. In free pbx a niektorých ďalších PBX sa hovor považuje za prijatý hneď, ako PBX zdvihne telefón. Ale pre hlasové menu už musíte zdvihnúť telefón, takže všetky hovory budú prijaté a čakacia doba na odpoveď bude 0-1 sekunda. Preto bolo rozhodnuté ušetriť nielen čas pred odpoveďou, ale aj čas pred spojením s kľúčovými modulmi (tento príznak nastavuje modul sám. Aktuálne je to „Zamestnanec“, „Externá linka“),
  • pri zložitejšom dialplane, keď hovor putuje medzi rôznymi skupinami, bolo potrebné mať možnosť skúmať každý prvok samostatne.

Ako najlepšia možnosť sa ukázalo, keď si moduly ústredne pri hovoroch posielajú informácie o sebe a v konečnom dôsledku si informácie ukladajú vo forme stromu.

Vyzerá to takto:

Najprv všeobecné informácie o hovore (ako všetci ostatní - nič zvláštne).

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

  1. Prijatý hovor na vonkajšej linke "Pre test"o 05:55:52 z čísla 89295671458 na číslo 89999999999, nakoniec odpovedal zamestnanec"tajomník2» s číslom 104. Klient čakal 60 sekúnd a hovoril 36 sekúnd.
  2. zamestnanec"tajomník2"zavolá na číslo 112 a zamestnanec odpovie"Manažér1» po 8 sekundách. Rozprávajú sa 14 sekúnd.
  3. Klient je prevedený na zamestnanca "manažér1“ kde pokračujú v rozhovore ďalších 13 sekúnd

Toto je však vrchol ľadovca, ku každému záznamu môžete získať podrobnú históriu hovorov prostredníctvom PBX.

Príbeh jedného projektu alebo ako som strávil 7 rokov vytváraním PBX na báze Asterisk a Php

Všetky informácie sú prezentované ako vnorené hovory:

  1. Prijatý hovor na vonkajšej linke "Pre test» o 05:55:52 z čísla 89295671458 na číslo 89999999999.
  2. O 05:55:53 vonkajšia linka odošle volanie do prichádzajúceho okruhu "test»
  3. Pri spracovaní hovoru podľa schémy sa modul „hovor manažéra“, pričom hovor trvá 16 sekúnd. Ide o modul vyvinutý pre klienta.
  4. modul"hovor manažéra" odošle hovor zamestnancovi zodpovednému za číslo (klientovi) "Manažér1“ a čaká 5 sekúnd na odpoveď. Manažér neodpovedal.
  5. modul"hovor manažéra"odošle hovor do skupiny"manažéri CORP" Sú to ďalší manažéri rovnakého smeru (sedia v rovnakej miestnosti) a čakajú 11 sekúnd na odpoveď.
  6. Skupina "manažéri CORP"volá zamestnancom"Manažér1, Manažér2, Manažér3“ súčasne na 11 sekúnd. Žiadna odpoveď.
  7. Hovor manažéra sa končí. A okruh odošle volanie modulu "Výber trasy z 1c" Tiež modul napísaný pre klienta. Tu bol hovor spracovávaný 0 sekúnd.
  8. Okruh odošle hovor do hlasového menu "Základné s dodatočným vytáčaním" Klient tam čakal 31 sekúnd, žiadne dodatočné vytáčanie nebolo.
  9. Schéma pošle výzvu skupine "sekretárky“, kde klient čakal 12 sekúnd.
  10. V skupine sa volajú 2 zamestnanci súčasne "tajomník1"A"tajomník2"a po 12 sekundách zamestnanec odpovie"tajomník2" Odpoveď na hovor sa duplikuje do rodičovských hovorov. Ukázalo sa, že v skupine odpovedal „tajomník2", pri volaní okruh odpovedal "tajomník2" a odpovedal na hovor na vonkajšej linke s "tajomník2".

Práve ukladanie informácií o každej operácii a ich vnorenie umožní jednoduché vytváranie reportov. Správa o hlasovom menu vám pomôže zistiť, do akej miery to pomáha alebo prekáža. Zostavte správu o zmeškaných hovoroch zamestnancami s prihliadnutím na to, že hovor bol zachytený, a preto sa nepovažuje za zmeškaný, a s prihliadnutím na to, že išlo o skupinový hovor a niekto iný odpovedal skôr, čo znamená, že hovor tiež nebol zmeškaný.

Takéto ukladanie informácií vám umožní vziať každú skupinu samostatne a určiť, ako efektívne to funguje, a vytvoriť graf zodpovedaných a zmeškaných skupín podľa hodín. Analýzou prenosov po pripojení k manažérovi môžete skontrolovať aj presnosť pripojenia k zodpovednému manažérovi.

Môžete urobiť aj celkom atypické štúdie, napríklad ako často čísla, ktoré nie sú v databáze, vytáčajú správnu klapku alebo koľko percent odchádzajúcich hovorov je presmerovaných na mobilný telefón.

Výsledok?

Na údržbu ústredne nie je potrebný špecialista, zvládne to aj najbežnejší správca - odskúšané v praxi.

Na úpravy nie sú potrební špecialisti so serióznou kvalifikáciou, stačí znalosť PHP, pretože Moduly už boli napísané pre protokol SIP, pre front, pre volanie zamestnanca a iné. Existuje obalová trieda pre hviezdička. Na vývoj modulu môže programátor (a v dobrom slova zmysle by mal) volať hotové moduly. A vedomosti hviezdička sú úplne zbytočné, ak klient požiada o pridanie stránky s nejakým novým prehľadom. Ale prax ukazuje, že hoci si programátori tretích strán dokážu poradiť, bez dokumentácie a bežného pokrytia komentárov sa cítia neisto, takže stále je čo zlepšovať.

Moduly môžu:

  • vytvoriť nové možnosti spracovania hovorov,
  • pridať nové bloky do webového rozhrania,
  • dediť z ktoréhokoľvek z existujúcich modulov, predefinovať funkcie a nahradiť ich, alebo jednoducho byť mierne upravenou kópiou,
  • pridajte svoje nastavenia do šablóny nastavení iných modulov a oveľa viac.

Nastavenia PBX cez API. Ako je popísané vyššie, všetky nastavenia sú uložené v databáze a načítané v čase hovoru, takže môžete zmeniť všetky nastavenia PBX cez API. Pri volaní API sa konfigurácia nevytvára a moduly sa nereštartujú, preto nezáleží na tom, koľko nastavení a zamestnancov máte. Požiadavky API sa vykonávajú rýchlo a navzájom sa neblokujú.

Pobočková ústredňa ukladá všetky kľúčové operácie s hovormi s dĺžkou trvania (čakanie/rozhovor), vnorením a v podmienkach pobočkovej ústredne (zamestnanec, skupina, vonkajšia linka, nie kanál, číslo). To vám umožňuje vytvárať rôzne zostavy pre konkrétnych klientov a väčšina práce spočíva vo vytvorení užívateľsky prívetivého rozhrania.

Čo bude ďalej, ukáže čas. Je ešte veľa nuancií, ktoré treba prerobiť, plánov je ešte veľa, no od vzniku 3. verzie ubehol rok a už teraz môžeme povedať, že nápad funguje. Hlavnou nevýhodou verzie 3 sú hardvérové ​​​​zdroje, ale to je zvyčajne to, za čo musíte zaplatiť za jednoduchosť vývoja.

Zdroj: hab.com

Pridať komentár