Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Tikrai daugelis iš jūsų, kaip ir aš, turėjote idėją padaryti kažką unikalaus. Šiame straipsnyje aprašysiu technines problemas ir sprendimus, su kuriais teko susidurti kuriant PBX. Galbūt tai padės kažkam apsispręsti dėl savo idėjos, o kažkam eiti nueitu keliu, nes man taip pat buvo naudinga pionierių patirtis.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Idėja ir pagrindiniai reikalavimai

Ir viskas prasidėjo tiesiog nuo meilės Asterisk (pastato ryšių programų karkasas), telefonijos ir įrenginių automatizavimas „FreePBX“ (žiniatinklio sąsaja, skirta Asterisk). Jei įmonės poreikiai būtų be specifikos ir patektų į galimybes „FreePBX“ - viskas puiku. Visas diegimas įvyko per 24 valandas, įmonė gavo sukonfigūruotą PBX, patogią sąsają ir trumpus mokymus bei palaikymą, jei pageidaujama.

Tačiau įdomiausios užduotys buvo nestandartinės ir tada nebuvo taip pasakiškai. Asterisk gali daug nuveikti, tačiau norint, kad žiniatinklio sąsaja veiktų, reikėjo sugaišti daug kartų daugiau laiko. Taigi maža detalė gali užtrukti daug ilgiau nei likusios PBX dalies įdiegimas. Ir esmė ne ta, kad sukurti žiniatinklio sąsają užtrunka daug laiko, o esmė yra architektūrinėse ypatybėse „FreePBX“. Architektūros požiūriai ir metodai „FreePBX“ buvo išdėstyta php4 metu, o tuo metu jau buvo php5.6 ant kurio buvo galima viską padaryti paprasčiau ir patogiau.

Paskutinis lašas buvo grafiniai planai diagramos pavidalu. Kai bandžiau sukurti kažką panašaus „FreePBX“, supratau, kad teks gerokai perrašyti ir bus lengviau kurti kažką naujo.

Pagrindiniai reikalavimai buvo šie:

  • paprasta sąranka, intuityviai prieinama net pradedančiajam administratoriui. Taigi, įmonės nereikalauja PBX priežiūros iš mūsų pusės,
  • lengvas modifikavimas, kad užduotys būtų išspręstos tinkamu laiku,
  • lengvas integravimas su PBX. U „FreePBX“ nustatymams keisti nebuvo API, t.y. Pavyzdžiui, negalite kurti grupių ar balso meniu iš trečiosios šalies programos, tik pačios API Asterisk,
  • atvirasis šaltinis - programuotojams tai labai svarbu modifikuojant klientą.

Spartesnio kūrimo idėja buvo, kad visas funkcionalumas būtų sudarytas iš modulių objektų pavidalu. Visi objektai turėjo turėti bendrą pirminę klasę, o tai reiškia, kad visų pagrindinių funkcijų pavadinimai jau žinomi, todėl jau yra numatytosios realizacijos. Objektai leis jums žymiai sumažinti argumentų skaičių asociatyvinių masyvų pavidalu su eilutės raktais, kuriuos galite sužinoti „FreePBX“ Tai buvo įmanoma išnagrinėjus visą funkciją ir įdėtas funkcijas. Objektų atveju banalus automatinis užbaigimas parodys visas savybes ir apskritai daug kartų supaprastins gyvenimą. Be to, paveldėjimas ir pakartotinis apibrėžimas jau išsprendžia daugybę modifikacijų problemų.

Kitas dalykas, kuris sulėtino perdirbimo laiką ir kurio buvo verta vengti, buvo dubliavimas. Jei yra modulis, atsakingas už darbuotojo rinkimą, visi kiti moduliai, kuriems reikia skambinti darbuotojui, turėtų jį naudoti, o ne kurti savo kopijas. Taigi, jei reikia ką nors keisti, tai keisti teks tik vienoje vietoje ir paieška „kaip veikia“ turėtų būti atliekama vienoje vietoje, o ne viso projekto metu.

Pirma versija ir pirmosios klaidos

Pirmasis prototipas buvo paruoštas per metus. Visas PBX, kaip ir planuota, buvo modulinis, o moduliai galėjo ne tik pridėti naujų skambučių apdorojimo funkcijų, bet ir pakeisti pačią žiniatinklio sąsają.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php
Taip, mintis sukurti telefono planą tokios schemos pavidalu nėra mano, bet tai labai patogu ir aš padariau tą patį Asterisk.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Rašydami modulį programuotojai jau galėjo:

  • susikurkite savo skambučių apdorojimo funkciją, kurią būtų galima patalpinti diagramoje, taip pat elementų meniu kairėje,
  • sukurkite savo puslapius žiniatinklio sąsajai ir pridėkite savo šablonus prie esamų puslapių (jei puslapio kūrėjas tai numatė),
  • pridėkite nustatymus prie pagrindinio nustatymų skirtuko arba sukurkite savo nustatymų skirtuką,
  • programuotojas gali paveldėti iš esamo modulio, pakeisti dalį funkcionalumo ir užregistruoti nauju pavadinimu arba pakeisti pradinį modulį.

Pavyzdžiui, taip galite sukurti savo balso meniu:

......
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__); //Подменить существующий модуль

Pirmieji sudėtingi įgyvendinimai atnešė pirmąjį pasididžiavimą ir pirmuosius nusivylimus. Džiaugiausi, kad pavyko, kad jau pavyko atkurti pagrindines savybes „FreePBX“. Džiaugiausi, kad žmonėms patiko schemos idėja. Dar buvo daug galimybių supaprastinti kūrimą, tačiau net ir tuo metu kai kurios užduotys jau buvo lengvinamos.

PBX konfigūracijos keitimo API nuvylė – rezultatas buvo visai ne toks, kokio norėjome. Aš laikiausi to paties principo kaip ir „FreePBX“, paspaudus mygtuką Taikyti, visa konfigūracija sukuriama iš naujo ir moduliai paleidžiami iš naujo.

Tai atrodo taip:

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php
*Dialplan yra taisyklė (algoritmas), pagal kurią apdorojamas skambutis.

Tačiau naudojant šią parinktį neįmanoma parašyti įprastos API PBX nustatymų keitimui. Pirma, pakeitimų taikymo operacija Asterisk per ilgas ir reikalaujantis daug išteklių.
Antra, negalite iškviesti dviejų funkcijų vienu metu, nes abu sukurs konfigūraciją.
Trečia, taiko visus nustatymus, įskaitant administratoriaus nustatytus nustatymus.

Šioje versijoje, kaip ir Askozia, buvo galima sugeneruoti tik pakeistų modulių konfigūraciją ir iš naujo paleisti tik reikalingus modulius, tačiau visa tai yra pusė priemonių. Reikėjo keisti požiūrį.

Antroji versija. Nosis ištraukta uodega įstrigo

Idėja išspręsti problemą buvo ne iš naujo sukurti konfigūraciją ir rinkimo planą Asterisk, bet išsaugokite informaciją duomenų bazėje ir nuskaitykite iš duomenų bazės tiesiogiai, kai apdorojate skambutį. Asterisk Aš jau mokėjau skaityti konfigūracijas iš duomenų bazės, tiesiog pakeiskite reikšmę duomenų bazėje ir kitas skambutis bus apdorotas atsižvelgiant į pakeitimus, o funkcija puikiai tiko nuskaityti telefono plano parametrus REALTIME_HASH.

Galiausiai net nereikėjo paleisti iš naujo Asterisk pakeitus nustatymus ir visi nustatymai buvo pradėti nedelsiant taikyti Asterisk.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Vieninteliai rinkimo plano pakeitimai yra plėtinių numerių pridėjimas ir patarimai. Tačiau tai buvo nedideli taškiniai pokyčiai

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)
...

Naudodami rinkimo planą galite lengvai pridėti arba pakeisti eilutę Ami (valdymo sąsaja Asterisk) ir nereikia perkrauti viso skambinimo plano.

Tai išsprendė konfigūracijos API problemą. Jūs netgi galite tiesiogiai įeiti į duomenų bazę ir pridėti naują grupę arba pakeisti, pavyzdžiui, skambinimo laiką grupės lauke „dialtime“ ir kitas skambutis jau truktų nurodytą laiką (tai nėra rekomendacija veiksmas, nes kai kurioms API operacijoms reikia Ami skambučiai).

Pirmieji sunkūs įgyvendinimai vėl atnešė pirmąjį pasididžiavimą ir nusivylimą. Džiaugiausi, kad pavyko. Duomenų bazė tapo kritine grandimi, padidėjo priklausomybė nuo disko, atsirado daugiau rizikų, bet viskas veikė stabiliai ir be problemų. Ir svarbiausia, kad dabar viską, ką galima padaryti per žiniatinklio sąsają, buvo galima padaryti per API, ir buvo naudojami tie patys metodai. Be to, žiniatinklio sąsaja atsikratė mygtuko „taikyti nustatymus PBX“, kurį administratoriai dažnai pamiršdavo.

Nusivylimas buvo tai, kad plėtra tapo sudėtingesnė. Nuo pirmosios versijos PHP kalba sugeneravo rinkimo planą šia kalba Asterisk ir atrodo visiškai neįskaitoma, plius pati kalba Asterisk rašyti telefono planą yra labai primityvu.

Kaip atrodė:

$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'))

Antroje versijoje telefono planas tapo universalus, į jį buvo įtrauktos visos galimos apdorojimo galimybės priklausomai nuo parametrų ir jo dydis žymiai padidėjo. Visa tai labai sulėtino kūrimo laiką, o pati mintis, kad dar kartą reikia kištis į dialplan, nuliūdino.

Trečia versija

Idėja išspręsti problemą nebuvo generuoti Asterisk dialplan iš php ir naudokite FastAGI ir parašykite visas apdorojimo taisykles pačiame PHP. FastAGI leidžia Asterisk, norėdami apdoroti skambutį, prijunkite prie lizdo. Iš ten gaukite komandas ir siųskite rezultatus. Taigi rinkimo plano logika jau yra už ribų Asterisk ir gali būti parašytas bet kuria kalba, mano atveju PHP.

Buvo daug bandymų ir klaidų. Pagrindinė problema buvo ta, kad jau turėjau daug klasių/failų. Objektams sukurti, inicijuoti ir užregistruoti vienas kitą prireikė maždaug 1,5 sekundės, o šio skambučio vėlavimo negalima ignoruoti.

Inicijavimas turėjo įvykti tik vieną kartą, todėl sprendimo paieška prasidėjo nuo paslaugos parašymo php naudojant P gijos. Po savaitės eksperimentavimo ši parinktis buvo atmesta dėl šio plėtinio veikimo sudėtingumo. Po mėnesio testavimo taip pat turėjau atsisakyti asinchroninio programavimo PHP; man reikėjo kažko paprasto, žinomo bet kuriam PHP pradedantiesiems, o daugelis PHP plėtinių yra sinchroniniai.

Sprendimas buvo mūsų pačių sukurta kelių gijų paslauga C, kuri buvo sudaryta naudojant PHPLIB. Įkelia visus ATS php failus, laukia, kol visi moduliai pradės inicijuoti, prideda vieną kitą atgalinį skambutį, o kai viskas paruošta – talpina. Kai teiraujasi per FastAGI sukuriamas srautas, jame atkuriama kopija iš visų klasių ir duomenų talpyklos, o užklausa perduodama php funkcijai.

Taikant šį sprendimą, laikas nuo skambučio išsiuntimo mūsų tarnybai iki pirmosios komandos Asterisk sumažėjo nuo 1,5 s iki 0,05 s ir šis laikas šiek tiek priklauso nuo projekto dydžio.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Dėl to žymiai sutrumpėjo telefono plano kūrimo laikas, ir aš galiu tai vertinti, nes turėjau perrašyti visą visų PHP modulių telefono planą. Pirma, metodai jau turėtų būti parašyti php, norint gauti objektą iš duomenų bazės; jie buvo reikalingi norint parodyti žiniatinklio sąsajoje, antra, ir tai yra pagrindinis dalykas, pagaliau galima patogiai dirbti su eilutėmis su skaičiais ir masyvais. su duomenų baze ir daugybe PHP plėtinių.

Norėdami apdoroti rinkimo planą modulio klasėje, turite įdiegti funkciją dialplanDynamicCall ir argumentas pbxCallRequest bus objektas, su kuriuo galima sąveikauti Asterisk.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Be to, tapo įmanoma derinti skambinimo planą (php turi xdebug ir jis veikia mūsų paslaugai), galite judėti žingsnis po žingsnio peržiūrėdami kintamųjų reikšmes.

Skambučių duomenys

Bet kokiai analizei ir ataskaitoms reikalingi teisingai surinkti duomenys, o šis PBX blokas taip pat patyrė daugybę bandymų ir klaidų nuo pirmosios iki trečiosios versijos. Dažnai skambučių duomenys yra ženklas. Vienas skambutis = vienas įrašas: kas skambino, kas atsiliepė, kiek laiko kalbėjo. Įdomesniuose variantuose yra papildomas ženklas, nurodantis, kuriam PBX darbuotojui buvo iškviesta pokalbio metu. Tačiau visa tai apima tik dalį poreikių.

Pradiniai reikalavimai buvo tokie:

  • išsaugoti ne tik kam skambino PBX, bet ir kas atsiliepė, nes yra perimimų ir į tai reikės atsižvelgti analizuojant skambučius,
  • laikas prieš susisiekiant su darbuotoju. Į „FreePBX“ ir kai kurių kitų PBX, į skambutį laikomas atsakytas, kai tik PBX pakelia ragelį. Bet balso meniu jau reikia pakelti ragelį, todėl į visus skambučius atsiliepiama ir atsakymo laukimo laikas tampa 0-1 sekundė. Todėl buvo nuspręsta sutaupyti ne tik laiką iki atsakymo, bet ir laiką iki prisijungimo prie pagrindinių modulių (šią vėliavėlę nustato pats modulis. Šiuo metu tai yra „Darbuotojas“, „Išorinė linija“),
  • sudėtingesniam rinkimo planui, kai skambutis keliauja tarp skirtingų grupių, reikėjo turėti galimybę nagrinėti kiekvieną elementą atskirai.

Geriausias variantas pasirodė, kai PBX moduliai siunčia informaciją apie save pokalbių metu ir galiausiai išsaugo informaciją medžio pavidalu.

Tai atrodo taip:

Pirma, bendra informacija apie skambutį (kaip ir visi kiti – nieko ypatingo).

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

  1. Sulaukiau skambučio išorine linija“Dėl tešlos"05:55:52 iš numerio 89295671458 į numerį 89999999999, galiausiai atsiliepė darbuotoja"Sekretorius 2» su numeriu 104. Klientas laukė 60 sekundžių ir kalbėjo 36 sekundes.
  2. Darbuotojas "Sekretorius 2„skambina 112 ir atsiliepia darbuotojas“Vadovas 1» po 8 sekundžių. Jie kalba 14 sekundžių.
  3. Klientas perkeliamas darbuotojui "vadovas1“, kur jie tęsia pokalbį dar 13 sekundžių

Tačiau tai yra ledkalnio viršūnė; kiekvienam įrašui galite gauti išsamią skambučių istoriją per PBX.

Vieno projekto istorija arba tai, kaip aš praleidau 7 metus kurdamas PBX pagal Asterisk ir Php

Visa informacija pateikiama kaip skambučių lizdas:

  1. Sulaukiau skambučio išorine linija“Dėl tešlos» 05:55:52 iš numerio 89295671458 į numerį 89999999999.
  2. 05:55:53 išorinė linija siunčia skambutį į įeinančią grandinę "testas»
  3. Apdorojant skambutį pagal schemą, modulis „vadovo skambutis“, kuriame skambutis trunka 16 sekundžių. Tai klientui sukurtas modulis.
  4. modulis "vadovo skambutis" siunčia skambutį darbuotojui, atsakingam už numerį (klientą)"Vadovas 1“ ir laukia 5 sekundes atsakymo. Vadovas neatsakė.
  5. modulis "vadovo skambutis"siunčia skambutį grupei"CORP vadovai“ Tai kiti tos pačios krypties vadovai (sėdintys tame pačiame kambaryje) ir laukiantys 11 sekundžių atsakymo.
  6. Grupė "CORP vadovai„skambina darbuotojams“Vadovas 1, Vadovas 2, Vadovas 3“ vienu metu 11 sekundžių. Nėra atsakymo.
  7. Vadovo pokalbis baigiasi. Ir grandinė siunčia skambutį į modulį "Maršruto pasirinkimas iš 1c“ Taip pat modulis, parašytas klientui. Čia skambutis buvo apdorotas 0 sekundžių.
  8. Grandinė siunčia skambutį į balso meniu "Pagrindinis su papildomu rinkimu“ Klientas ten laukė 31 sekundę, papildomo rinkimo nebuvo.
  9. Schema siunčia skambutį grupei "Sekretoriai“, kur klientas laukė 12 sekundžių.
  10. Grupėje vienu metu kviečiami 2 darbuotojai "Sekretorius 1"Ir"Sekretorius 2"ir po 12 sekundžių darbuotojas atsako"Sekretorius 2“ Atsakymas į skambutį dubliuojamas į tėvų skambučius. Pasirodo, grupėje jis atsakė „Sekretorius 2", skambinant į grandinę atsiliepė"Sekretorius 2ir atsiliepė į skambutį išorinėje linijojeSekretorius 2".

Būtent informacijos apie kiekvieną operaciją išsaugojimas ir jų įdėjimas leis tiesiog rengti ataskaitas. Balso meniu ataskaita padės išsiaiškinti, kiek tai padeda ar trukdo. Sukurkite darbuotojų praleistų skambučių ataskaitą, atsižvelgdami į tai, kad skambutis buvo perimtas ir todėl nelaikomas praleistu, ir į tai, kad tai buvo grupinis skambutis, o kažkas atsiliepė anksčiau, vadinasi, skambutis taip pat nebuvo praleistas.

Toks informacijos saugojimas leis paimti kiekvieną grupę atskirai ir nustatyti, kaip efektyviai ji veikia, bei sudaryti atsakytų ir praleistų grupių grafiką pagal valandas. Taip pat galite patikrinti, kiek tikslus yra ryšys su atsakingu vadovu, išanalizavę pervedimus prisijungus prie vadovo.

Taip pat galite atlikti gana netipiškus tyrimus, pavyzdžiui, kaip dažnai duomenų bazėje nesantys numeriai surenka teisingą plėtinį arba koks procentas išeinančių skambučių nukreipiamas į mobilųjį telefoną.

Rezultatas?

Specialistas neprivalo prižiūrėti PBX, tai gali padaryti paprasčiausias administratorius – išbandytas praktiškai.

Modifikacijoms nereikia rimtos kvalifikacijos specialistų, pakanka PHP žinių, nes Moduliai jau parašyti ir SIP protokolui, ir eilei, ir darbuotojo iškvietimui, ir kt. Yra vyniojimo klasė Asterisk. Norėdami sukurti modulį, programuotojas gali (ir geru būdu turėtų) iškviesti paruoštus modulius. Ir žinios Asterisk yra visiškai nereikalingi, jei klientas prašo pridėti puslapį su kokia nors nauja ataskaita. Tačiau praktika rodo, kad nors trečiųjų šalių programuotojai gali susidoroti, jie jaučiasi nesaugūs be dokumentacijos ir įprasto komentarų aprėpties, todėl tobulėti dar yra kur.

Moduliai gali:

  • sukurti naujas skambučių apdorojimo galimybes,
  • pridėti naujų blokų prie žiniatinklio sąsajos,
  • paveldėti iš bet kurio esamo modulio, iš naujo apibrėžti funkcijas ir ją pakeisti arba tiesiog būti šiek tiek pakeista kopija,
  • pridėkite savo nustatymus prie kitų modulių nustatymų šablono ir dar daugiau.

PBX nustatymai per API. Kaip aprašyta aukščiau, visi nustatymai saugomi duomenų bazėje ir nuskaitomi skambučio metu, todėl per API galite pakeisti visus PBX nustatymus. Iškviečiant API, konfigūracija nėra atkuriama ir moduliai nepaleidžiami iš naujo, todėl nesvarbu, kiek nustatymų ir darbuotojų turite. API užklausos vykdomos greitai ir viena kitos neblokuoja.

PBX saugo visas pagrindines operacijas su skambučiais su trukme (laukimas / pokalbis), įdėjimu ir PBX terminais (darbuotojas, grupė, išorinė linija, o ne kanalas, numeris). Tai leidžia kurti įvairias ataskaitas konkretiems klientams, o didžioji dalis darbo yra sukurti patogią sąsają.

Laikas parodys, kas bus toliau. Dar yra daug niuansų, kuriuos reikia perdaryti, dar daug planų, bet praėjo metai nuo 3-iosios versijos sukūrimo ir jau galime teigti, kad idėja veikia. Pagrindinis 3 versijos trūkumas yra aparatinės įrangos ištekliai, tačiau dažniausiai už tai reikia mokėti, kad būtų lengviau kurti.

Šaltinis: www.habr.com

Добавить комментарий