Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Kindlasti oli paljudel teist, nagu minulgi, idee teha midagi ainulaadset. Selles artiklis kirjeldan tehnilisi probleeme ja lahendusi, millega pidin PBX-i arendamisel silmitsi seisma. Võib-olla aitab see kellelgi oma idee üle otsustada ja kellelgi käia sissetallatud radadel, sest ka mina sain pioneeride kogemusest kasu.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Idee ja põhinõuded

Ja see kõik algas lihtsalt armastusest Tärniga (siderakenduste ehitamise raamistik), telefoni ja paigaldiste automatiseerimine FreePBX (veebiliides jaoks Tärniga). Kui ettevõtte vajadused oleksid spetsiifilised ja jääksid võimaluste piiresse FreePBX - kõik on hästi. Kogu paigaldus toimus XNUMX tunni jooksul, ettevõte sai konfigureeritud PBX-i, kasutajasõbraliku liidese ja lühikese koolituse pluss soovi korral tugi.

Kuid kõige huvitavamad ülesanded olid ebastandardsed ja siis polnud see enam nii vapustav. Tärniga saab teha palju, kuid veebiliidese töökorras hoidmiseks oli vaja kulutada kordades rohkem aega. Nii et väike detail võib võtta palju kauem aega kui ülejäänud PBX-i installimine. Ja asi pole selles, et veebiliidese kirjutamine võtab kaua aega, vaid asi on pigem arhitektuurilistes omadustes FreePBX. Arhitektuuri lähenemisviisid ja meetodid FreePBX oli php4 ajal välja pandud ja sel hetkel oli juba php5.6 mille peal sai kõike lihtsamaks ja mugavamaks teha.

Viimaseks õlekõrreks olid graafilised valimisplaanid diagrammi kujul. Kui ma proovisin midagi sellist ehitada FreePBX, sain aru, et pean selle oluliselt ümber kirjutama ja lihtsam on midagi uut ehitada.

Peamised nõuded olid:

  • lihtne seadistamine, intuitiivselt juurdepääsetav isegi algajale administraatorile. Seega ei vaja ettevõtted meie poolelt PBX-i hooldust,
  • lihtne muutmine, nii et ülesanded lahendatakse õigeaegselt,
  • PBX-iga integreerimise lihtsus. U FreePBX seadete muutmiseks polnud API-d, st. Te ei saa näiteks luua rühmi ega häälmenüüd kolmanda osapoole rakendusest, vaid ainult API-st endast Tärniga,
  • avatud lähtekoodiga - programmeerijate jaoks on see kliendi modifikatsioonide jaoks äärmiselt oluline.

Kiirema arenduse idee oli, et kogu funktsionaalsus koosneks objektide kujul olevatest moodulitest. Kõikidel objektidel pidi olema ühine vanemklass, mis tähendab, et kõigi põhifunktsioonide nimed on juba teada ja seetõttu on olemas juba vaikerakendused. Objektid võimaldavad teil dramaatiliselt vähendada argumentide arvu stringivõtmetega assotsiatiivsete massiivide kujul, mida saate teada FreePBX See oli võimalik kogu funktsiooni ja pesastatud funktsioonide uurimisel. Objektide puhul näitab banaalne automaatne lõpetamine kõiki omadusi ja üldiselt lihtsustab see elu mitu korda. Lisaks lahendab pärimine ja uuesti määratlemine juba palju modifikatsioonidega seotud probleeme.

Järgmine asi, mis ümbertöötamise aega pidurdas ja mida tasus vältida, oli dubleerimine. Kui töötajale helistamise eest vastutav moodul on olemas, peaksid kõik muud moodulid, mis peavad töötajale kõne saatma, kasutama seda, mitte looma oma koopiaid. Seega, kui teil on vaja midagi muuta, peate muutma ainult ühes kohas ja otsingut “kuidas see toimib” tuleks teha ühes kohas, mitte kogu projekti vältel.

Esimene versioon ja esimesed vead

Esimene prototüüp valmis aastaga. Kogu PBX, nagu plaanitud, oli modulaarne ja moodulid ei saanud mitte ainult lisada uusi funktsioone kõnede töötlemiseks, vaid muuta ka veebiliidest ennast.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues
Jah, sellise skeemi vormis valimisplaani koostamise idee ei ole minu oma, kuid see on väga mugav ja ma tegin sama Tärniga.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Mooduli kirjutamisega saaksid programmeerijad juba:

  • looge kõne töötlemiseks oma funktsionaalsus, mille saab paigutada nii diagrammile kui ka vasakpoolsesse elementide menüüsse,
  • looge veebiliidese jaoks oma lehed ja lisage oma mallid olemasolevatele lehtedele (kui lehe arendaja on selle ette näinud),
  • lisage oma seaded põhisätete vahekaardile või looge oma seadete vahekaart,
  • programmeerija saab pärida olemasolevalt moodulilt, muuta osa funktsionaalsusest ja registreerida selle uue nime all või asendada algse mooduli.

Näiteks saate oma häälmenüü luua järgmiselt.

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

Esimesed keerulised teostused tõid kaasa esimese uhkuse ja esimesed pettumused. Mul oli hea meel, et see töötas, et sain juba põhiomadused taasesitada FreePBX. Mul oli hea meel, et skeemi idee inimestele meeldis. Võimalusi arenduse lihtsustamiseks oli veel palju, kuid ka sel ajal tehti osa ülesandeid juba lihtsamaks.

PBX-i konfiguratsiooni muutmise API valmistas pettumuse – tulemus polnud üldse see, mida tahtsime. Võtsin sama põhimõtte, mis siin FreePBX, klõpsates nuppu Rakenda, luuakse kogu konfiguratsioon uuesti ja moodulid taaskäivitatakse.

See näeb välja selline:

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues
*Dialplan on reegel (algoritm), mille järgi kõnet töödeldakse.

Kuid selle valikuga on võimatu kirjutada tavalist API-d PBX-i sätete muutmiseks. Esiteks muudatuste rakendamise toiming Tärniga liiga pikk ja ressursimahukas.
Teiseks ei saa te kahte funktsiooni korraga kutsuda, sest mõlemad loovad konfiguratsiooni.
Kolmandaks rakendab see kõiki sätteid, sealhulgas neid, mille on teinud administraator.

Selles versioonis, nagu ka Askozia, oli võimalik genereerida ainult muudetud moodulite konfiguratsioon ja taaskäivitada ainult vajalikud moodulid, kuid need on kõik pooled mõõdud. Oli vaja lähenemist muuta.

Teine versioon. Väljatõmmatud nina saba kinni

Probleemi lahendamise idee ei olnud konfiguratsiooni ja valimisplaani uuesti loomine Tärniga, kuid salvestage teave andmebaasi ja lugege kõne töötlemise ajal otse andmebaasist. Tärniga Teadsin juba andmebaasist seadistusi lugeda, muuda lihtsalt väärtust andmebaasis ja järgmine kõne töödeldakse muudatusi arvesse võttes ning funktsioon sobis suurepäraselt dialplan parameetrite lugemiseks REALTIME_HASH.

Lõpuks polnud vaja isegi restart teha Tärniga seadete muutmisel ja kõiki sätteid hakati kohe rakendama Tärniga.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Ainsad muudatused valimisplaanis on laiendite numbrite lisamine ja vihjed. Kuid need olid väikesed muudatused

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

Saate hõlpsasti lisada või muuta valimisplaani rida kasutades Ami (juhtimisliides Tärniga) ja kogu valimisplaani taaskäivitamine pole vajalik.

See lahendas probleemi konfiguratsiooni API-ga. Võite isegi otse andmebaasi siseneda ja lisada uue grupi või muuta näiteks grupi väljal "heliaeg" sissehelistamisaega ja järgmine kõne kestaks juba määratud aja (see ei ole soovitus toiming, kuna mõned API toimingud nõuavad Ami kõned).

Esimesed rasked teostused tõid taas esimese uhkuse ja pettumuse. Mul oli hea meel, et see töötas. Andmebaas muutus kriitiliseks lüliks, sõltuvus kettast suurenes, riske oli rohkem, aga kõik töötas stabiilselt ja probleemideta. Ja mis kõige tähtsam, nüüd sai kõike, mida sai teha läbi veebiliidese, teha läbi API ja kasutati samu meetodeid. Lisaks vabanes veebiliides nupust "Rakenda seaded PBX-ile", mille administraatorid sageli unustasid.

Pettumus oli see, et arendus läks keerulisemaks. Alates esimesest versioonist on PHP keel loonud selles keeles valimisplaani Tärniga ja see tundub täiesti loetamatu, pluss keel ise Tärniga valimisplaani kirjutamiseks on see äärmiselt primitiivne.

Kuidas see välja nägi:

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

Teises versioonis sai valimisplaan universaalseks, see hõlmas kõiki võimalikke töötlemisvõimalusi sõltuvalt parameetritest ja selle suurus suurenes oluliselt. See kõik pidurdas kõvasti arendusaega ja juba ainuüksi mõte, et taaskord on vaja dialplan segada, tegi kurvaks.

Kolmas versioon

Probleemi lahendamise mõte ei olnud genereerida Tärniga Dialplan php-st ja kasuta FastAGI ja kirjutage kõik töötlemisreeglid PHP-s endas. FastAGI võimaldab Tärniga, kõne töötlemiseks ühendage pistikupessa. Saate sealt käsklusi ja saada tulemusi. Seega on valimisplaani loogika juba väljaspool piire Tärniga ja seda saab kirjutada mis tahes keeles, minu puhul PHP-s.

Katse-eksitusi oli palju. Põhiprobleem oli selles, et mul oli juba palju klasse/faile. Objektide loomiseks, lähtestamiseks ja üksteisega registreerimiseks kulus umbes 1,5 sekundit ning seda viivitust kõne kohta ei saa ignoreerida.

Initsialiseerimine oleks pidanud toimuma vaid korra ja seetõttu sai lahenduse otsimine alguse php-s teenuse kirjutamisest Plõimed. Pärast nädal aega kestnud katsetamist jäeti see valik riiulile selle laienduse toimimise keerukuse tõttu. Pärast kuu aega kestnud testimist pidin loobuma ka PHP-s asünkroonsest programmeerimisest, vajasin midagi lihtsat, mis on tuttav igale PHP-algajale ja paljud PHP laiendused on sünkroonsed.

Lahenduseks oli meie enda mitmelõimeline teenus C-s, millega kompileeriti PHPLIB. See laadib kõik ATS php failid, ootab kõigi moodulite initsialiseerumist, lisab üksteisele tagasihelistamise ja kui kõik on valmis, salvestab selle vahemällu. Kui pärida FastAGI luuakse voog, kõigi klasside ja andmete vahemälust koopia reprodutseeritakse selles ning päring edastatakse php funktsioonile.

Selle lahenduse korral kulub meie teenindusele kõne saatmisest kuni esimese käsuni Tärniga vähenes 1,5 sekundilt 0,05 sekundile ja see aeg sõltub veidi projekti suurusest.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Selle tulemusel vähenes märkimisväärselt valimisplaani arendamiseks kuluv aeg ja ma hindan seda, kuna pidin PHP kõigi moodulite kogu valimisplaani ümber kirjutama. Esiteks tuleks php-s juba meetodid andmebaasist objekti hankimiseks kirjutada, neid oli vaja veebiliideses kuvamiseks ja teiseks, ja see on peamine, on lõpuks võimalik mugavalt töötada numbrite ja massiividega stringidega andmebaasi ja paljude PHP laiendustega.

Mooduliklassis oleva valimisplaani töötlemiseks peate funktsiooni rakendama dialplanDynamicCall ja argument pbxCallRequest sisaldab objekti, millega suhelda Tärniga.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Lisaks sai võimalikuks sissehelistamisplaani silumine (php-l on xdebug ja see töötab meie teenuse jaoks), saate liikuda samm-sammult, vaadates muutujate väärtusi.

Kõneandmed

Igasugune analüüs ja aruanded nõuavad korrektselt kogutud andmeid ning ka see PBX-plokk läbis esimesest kuni kolmanda versioonini palju katse-eksitusi. Sageli on kõneandmed märk. Üks kõne = üks salvestus: kes helistas, kes vastas, kui kaua nad rääkisid. Huvitavamatel valikutel on lisamärk, mis näitab, millisele PBX töötajale kõne ajal helistati. Kuid see kõik katab vaid osa vajadustest.

Esialgsed nõuded olid järgmised:

  • salvestage mitte ainult see, kellele PBX helistas, vaid ka seda, kes vastas, sest esineb pealtkuulamisi ja seda tuleb kõnede analüüsimisel arvesse võtta,
  • aega enne töötajaga ühenduse loomist. sisse FreePBX ja mõned teised PBX-id, loetakse kõne vastatuks kohe, kui PBX telefoni vastu võtab. Aga häälmenüü jaoks tuleb juba telefon haarata, nii et kõik kõned võetakse vastu ja vastuse ooteaeg muutub 0-1 sekundiks. Seetõttu otsustati säästa mitte ainult aega enne vastust, vaid aega enne võtmemoodulitega ühenduse loomist (moodul ise määrab selle lipu. Praegu on see “Töötaja”, “Välisliin”),
  • keerulisema valimisplaani jaoks, kui kõne liigub erinevate rühmade vahel, oli vaja iga elementi eraldi uurida.

Parimaks variandiks osutus see, kui PBX-moodulid saadavad kõnede ajal enda kohta infot ja salvestavad lõpuks info puu kujul.

See näeb välja selline:

Esiteks üldine teave kõne kohta (nagu kõik teised - ei midagi erilist).

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

  1. Sai kõne välisliinil"Tainas"kell 05:55:52 numbrilt 89295671458 numbrile 89999999999, lõpuks vastas töötaja"Sekretär 2» numbriga 104. Klient ootas 60 sekundit ja rääkis 36 sekundit.
  2. Töötaja"Sekretär 2"helistab numbrile 112 ja töötaja vastab"Juht 1» 8 sekundi pärast. Nad räägivad 14 sekundit.
  3. Klient läheb üle Töötajale "juht 1" kus nad jätkavad juttu veel 13 sekundit

Kuid see on jäämäe tipp: iga kirje kohta saate PBX-i kaudu üksikasjaliku kõneajaloo.

Ühe projekti lugu ehk kuidas ma veetsin 7 aastat Asteriskil ja Php-l põhinevat PBX-i luues

Kogu teave esitatakse kõnede pesastusena:

  1. Sai kõne välisliinil"Tainas» kell 05:55:52 numbrilt 89295671458 numbrile 89999999999.
  2. Kell 05:55:53 saadab välisliin kõne sissetulevasse ahelasse "test»
  3. Kõne töötlemisel vastavalt skeemile kuvatakse moodul "juhataja kõne", milles kõne on 16 sekundit. See on kliendi jaoks välja töötatud moodul.
  4. moodul "juhataja kõne" saadab kõne numbri eest vastutavale töötajale (kliendile)"Juht 1” ja ootab 5 sekundit vastust. Juhataja ei vastanud.
  5. moodul "juhataja kõne"saadab kõne grupile"CORP juhid" Need on teised sama suuna juhid (istuvad samas ruumis) ja ootavad 11 sekundit vastust.
  6. Grupp "CORP juhid"helistab töötajatele"Juht 1, Juht 2, Juht 3"samaaegselt 11 sekundit. Vastust pole.
  7. Juhataja kõne lõppeb. Ja ahel saadab kõne moodulile "Marsruudi valimine punktist 1c" Samuti kliendile kirjutatud moodul. Siin töödeldi kõnet 0 sekundit.
  8. Ahel saadab kõne häälmenüüsse "Põhiline koos lisavalimisega" Klient ootas seal 31 sekundit, lisavalimist polnud.
  9. Skeem saadab kõne rühmale "Sekretärid", kus klient ootas 12 sekundit.
  10. Grupis kutsutakse korraga 2 töötajat "Sekretär 1"Ja"Sekretär 2"ja 12 sekundi pärast vastab töötaja"Sekretär 2" Kõne vastus dubleeritakse vanemate kõnedeks. Selgub, et rühmas vastas ta "Sekretär 2", vastas ringkonnale helistades"Sekretär 2" ja vastas välisliini kõnele "Sekretär 2'.

Just iga toimingu ja nende pesastamise kohta teabe salvestamine võimaldab lihtsalt aruandeid koostada. Häälmenüü aruanne aitab teil teada saada, kui palju see aitab või takistab. Koostage töötajate vastamata kõnede aruanne, võttes arvesse, et kõne oli pealtkuulatud ja seetõttu ei loeta vastamata, ning arvestades, et tegemist oli grupikõnega ja keegi teine ​​vastas varem, mis tähendab, et kõne ei jäänud ka vastamata.

Selline teabe salvestamine võimaldab teil võtta iga rühma eraldi ja määrata, kui tõhusalt see töötab, ning koostada vastatud ja vastamata rühmade graafik tundide kaupa. Samuti saate kontrollida, kui täpne on ühendus vastutava halduriga, analüüsides pärast halduriga ühenduse loomist ülekandeid.

Samuti saab teha üsna ebatüüpilisi uuringuid, näiteks kui sageli valivad numbrid, mida andmebaasis ei ole, õiget laiendit või kui suur protsent väljaminevatest kõnedest suunatakse mobiiltelefoni.

Ja tulemus?

PBX-i hooldama ei pea spetsialist, sellega saab hakkama kõige tavalisem administraator – praktikas testitud.

Muudatuste jaoks pole vaja tõsise kvalifikatsiooniga spetsialiste, piisab PHP tundmisest, sest Moodulid on juba kirjutatud SIP-protokolli ja järjekorra jaoks ja töötaja helistamiseks jm. Selleks on ümbrisklass Tärniga. Mooduli arendamiseks saab programmeerija (ja heas mõttes peakski) valmis mooduleid välja kutsuma. Ja teadmised Tärniga on täiesti ebavajalikud, kui klient soovib lisada lehe mõne uue aruandega. Kuid praktika näitab, et kuigi kolmandate osapoolte programmeerijad saavad hakkama, tunnevad nad end ilma dokumentatsioonita ja kommentaaride tavapärase katmiseta ebakindlalt, seega on arenguruumi veel.

Moodulid võivad:

  • luua uusi kõnetöötlusvõimalusi,
  • lisage veebiliidesesse uusi plokke,
  • pärida mis tahes olemasolevast moodulist, määratleda funktsioonid uuesti ja asendada see või olla lihtsalt veidi muudetud koopia,
  • lisage oma sätted teiste moodulite seadete malli ja palju muud.

PBX-i seaded API kaudu. Nagu ülalpool kirjeldatud, salvestatakse kõik seaded andmebaasi ja loetakse kõne ajal, nii et saate API kaudu kõiki PBX-i sätteid muuta. API helistamisel konfiguratsiooni uuesti ei looda ja mooduleid ei taaskäivitata, mistõttu pole vahet, kui palju seadeid ja töötajaid teil on. API päringud täidetakse kiiresti ega blokeeri üksteist.

PBX salvestab kõik võtmetoimingud kõnede kestusega (ootamine/vestlus), pesastamise ja PBX terminites (töötaja, rühm, välisliin, mitte kanal, number). See võimaldab koostada erinevaid aruandeid konkreetsetele klientidele ja suurem osa tööst on kasutajasõbraliku liidese loomine.

Eks aeg näitab, mis edasi saab. Veel on palju nüansse, mis vajavad ümbertegemist, plaane on veel palju, aga 3. versiooni loomisest on aasta möödas ja võib juba öelda, et idee töötab. Versiooni 3 peamiseks puuduseks on riistvararessursid, kuid tavaliselt peate arendamise hõlbustamiseks maksma selle eest.

Allikas: www.habr.com

Lisa kommentaar