Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Baie van julle, soos ek, het sekerlik 'n idee gehad om iets uniek te doen. In hierdie artikel sal ek die tegniese probleme en oplossings beskryf waarmee ek te kampe gehad het met die ontwikkeling van die PBX. Miskien sal dit iemand help om op hul eie idee te besluit, en iemand om die bewandelde pad te volg, want ek het ook baat gevind by die ervaring van pioniers.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Idee en sleutelvereistes

En dit het alles begin bloot met liefde vir asterisk (raamwerk vir die bou van kommunikasietoepassings), outomatisering van telefonie en installasies GratisPBX (webkoppelvlak vir asterisk). As die maatskappy se behoeftes sonder besonderhede was en binne die vermoëns geval het GratisPBX - alles is wonderlik. Die hele installasie het binne XNUMX uur plaasgevind, die maatskappy het 'n gekonfigureerde PBX, 'n gebruikersvriendelike koppelvlak en kort opleiding plus ondersteuning ontvang indien verlang.

Maar die interessantste take was nie-standaard en dan was dit nie so fantasties nie. asterisk kan baie doen, maar om die webkoppelvlak in werkende toestand te hou, was dit nodig om baie keer meer tyd te spandeer. So 'n klein detail kan baie langer neem as om die res van die PBX te installeer. En die punt is nie dat dit lank neem om 'n webkoppelvlak te skryf nie, maar eerder die punt is in die argitektoniese kenmerke GratisPBX. Argitektuurbenaderings en -metodes GratisPBX was ten tyde van php4 uitgelê, en op daardie oomblik was daar reeds php5.6 waarop alles eenvoudiger en geriefliker gemaak kon word.

Die laaste strooi was grafiese skakelplanne in die vorm van 'n diagram. Toe ek probeer het om so iets te bou vir GratisPBX, Ek het besef dat ek dit aansienlik sal moet herskryf en dit sal makliker wees om iets nuuts te bou.

Die sleutelvereistes was:

  • eenvoudige opstelling, intuïtief toeganklik selfs vir 'n beginner administrateur. Maatskappye benodig dus nie PBX-onderhoud aan ons kant nie,
  • maklike wysiging sodat take betyds opgelos word,
  • gemak van integrasie met PBX. U GratisPBX daar was geen API om instellings te verander nie, d.w.s. Jy kan byvoorbeeld nie groepe of stemkieslyste vanaf 'n derdeparty-toepassing skep nie, net die API self asterisk,
  • opensource - vir programmeerders is dit uiters belangrik vir wysigings vir die kliënt.

Die idee van vinniger ontwikkeling was om al die funksionaliteit uit modules in die vorm van voorwerpe te laat bestaan. Alle voorwerpe moes 'n gemeenskaplike ouerklas hê, wat beteken die name van al die hooffunksies is reeds bekend en daarom is daar reeds verstekimplementerings. Voorwerpe sal jou toelaat om die aantal argumente in die vorm van assosiatiewe skikkings met stringsleutels dramaties te verminder, wat jy kan uitvind in GratisPBX Dit was moontlik deur die hele funksie en geneste funksies te ondersoek. In die geval van voorwerpe, sal banale outovoltooiing al die eienskappe wys, en sal oor die algemeen die lewe baie keer vereenvoudig. Plus, oorerwing en herdefinisie los reeds baie probleme met wysigings op.

Die volgende ding wat die herwerktyd vertraag het en die moeite werd was om te vermy, was duplisering. As daar 'n module is wat verantwoordelik is om 'n werknemer te skakel, moet alle ander modules wat 'n oproep na 'n werknemer moet stuur dit gebruik, en nie hul eie kopieë skep nie. Dus, as jy iets moet verander, sal jy net op een plek moet verander en die soektog na "hoe dit werk" moet op een plek uitgevoer word, en nie deur die hele projek gesoek word nie.

Eerste weergawe en eerste foute

Die eerste prototipe was binne 'n jaar gereed. Die hele PBX, soos beplan, was modulêr, en die modules kon nie net nuwe funksionaliteit vir die verwerking van oproepe byvoeg nie, maar ook die webkoppelvlak self verander.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php
Ja, die idee om 'n skakelplan in die vorm van so 'n skema te bou is nie myne nie, maar dit is baie gerieflik en ek het dieselfde gedoen vir asterisk.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Deur 'n module te skryf, kon programmeerders reeds:

  • skep jou eie funksionaliteit vir oproepverwerking, wat op die diagram geplaas kan word, sowel as in die menu van elemente aan die linkerkant,
  • skep jou eie bladsye vir die webkoppelvlak en voeg jou sjablone by bestaande bladsye (as die bladsy-ontwikkelaar hiervoor voorsiening gemaak het),
  • voeg jou instellings by die hoofinstellingsoortjie of skep jou eie instellingsoortjie,
  • die programmeerder kan van 'n bestaande module erf, 'n deel van die funksionaliteit verander en dit onder 'n nuwe naam registreer of die oorspronklike module vervang.

Byvoorbeeld, dit is hoe jy jou eie stemkieslys kan skep:

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

Die eerste komplekse implementerings het die eerste trots en die eerste teleurstellings gebring. Ek was bly dat dit gewerk het, dat ek reeds die hoofkenmerke kon weergee GratisPBX. Ek was bly dat mense van die idee van die skema gehou het. Daar was nog baie opsies om ontwikkeling te vereenvoudig, maar selfs in daardie tyd is van die take reeds makliker gemaak.

Die API vir die verandering van die PBX-konfigurasie was 'n teleurstelling - die resultaat was glad nie wat ons wou hê nie. Ek het dieselfde beginsel as in GratisPBX, deur op die Toepas-knoppie te klik, word die hele konfigurasie herskep en word die modules herbegin.

Dit lyk so:

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php
*Dialplan is 'n reël (algoritme) waarvolgens 'n oproep verwerk word.

Maar met hierdie opsie is dit onmoontlik om 'n normale API te skryf om die PBX-instellings te verander. Eerstens, die werking van die toepassing van veranderinge op asterisk te lank en hulpbronintensief.
Tweedens kan jy nie twee funksies op dieselfde tyd oproep nie, want beide sal die konfigurasie skep.
Derdens pas dit alle instellings toe, insluitend dié wat deur die administrateur gemaak is.

In hierdie weergawe, soos in Askozia, was dit moontlik om die konfigurasie van slegs veranderde modules te genereer en net die nodige modules te herbegin, maar dit is alles halwe maatreëls. Dit was nodig om die benadering te verander.

Tweede weergawe. Neus uitgetrek stert vas

Die idee om die probleem op te los was nie om die konfigurasie en skakelplan vir te herskep nie asterisk, maar stoor inligting in die databasis en lees direk vanaf die databasis terwyl die oproep verwerk word. asterisk Ek het reeds geweet hoe om konfigurasies vanaf die databasis te lees, verander net die waarde in die databasis en die volgende oproep sal verwerk word met inagneming van die veranderinge, en die funksie was perfek vir die lees van skakelplan-parameters REALTIME_HASH.

Op die ou end was dit nie nodig om eers weer te begin nie asterisk wanneer die instellings verander word en al die instellings begin onmiddellik toegepas word op asterisk.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Die enigste veranderinge aan die skakelplan is die byvoeging van uitbreidingsnommers en wenke. Maar dit was klein kol veranderinge

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

Jy kan maklik 'n reël in die skakelplan byvoeg of verander met behulp van Ami (beheer koppelvlak asterisk) en geen herlaai van die hele skakelplan is nodig nie.

Dit het die probleem met die konfigurasie-API opgelos. Jy kan selfs direk in die databasis ingaan en 'n nuwe groep byvoeg of byvoorbeeld die inbeltyd in die "dialtime"-veld vir die groep verander en die volgende oproep sal reeds die gespesifiseerde tyd duur (Dit is nie 'n aanbeveling vir aksie, aangesien sommige API-bewerkings vereis Ami oproepe).

Die eerste moeilike implementerings het weer die eerste trots en teleurstelling gebring. Ek was bly dat dit gewerk het. Die databasis het 'n kritieke skakel geword, die afhanklikheid van die skyf het toegeneem, daar was meer risiko's, maar alles het stabiel en sonder probleme gewerk. En die belangrikste, nou kan alles wat deur die webkoppelvlak gedoen kan word deur die API gedoen word, en dieselfde metodes is gebruik. Boonop het die webkoppelvlak ontslae geraak van die "pas instellings toe op PBX"-knoppie, waarvan administrateurs dikwels vergeet het.

Die teleurstelling was dat die ontwikkeling meer ingewikkeld geraak het. Sedert die eerste weergawe het die PHP-taal 'n skakelplan in die taal gegenereer asterisk en dit lyk heeltemal onleesbaar, plus die taal self asterisk vir die skryf van 'n skakelplan is dit uiters primitief.

Hoe dit gelyk het:

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

In die tweede weergawe het die skakelplan universeel geword, dit het alle moontlike verwerkingsopsies ingesluit, afhangende van die parameters, en die grootte daarvan het aansienlik toegeneem. Dit alles het die ontwikkelingstyd baie vertraag, en die einste gedagte dat dit weer nodig was om met die skakelplan in te meng, het my hartseer gemaak.

Derde weergawe

Die idee om die probleem op te los was nie om te genereer nie asterisk dialplan vanaf php en gebruik FastAGI en skryf alle verwerkingsreëls in PHP self. FastAGI dit laat asterisk, om die oproep te verwerk, koppel aan die sok. Ontvang opdragte van daar af en stuur resultate. Die logika van die skakelplan is dus reeds buite die grense asterisk en kan in enige taal geskryf word, in my geval in PHP.

Daar was baie beproewing en fout. Die grootste probleem was dat ek reeds baie klasse/lêers gehad het. Dit het ongeveer 1,5 sekondes geneem om voorwerpe te skep, dit te inisialiseer en mekaar by mekaar te registreer, en hierdie vertraging per oproep is nie iets wat geïgnoreer kan word nie.

Inisialisering moes net een keer gebeur het en daarom het die soektog na 'n oplossing begin met die skryf van 'n diens in php met behulp van Pthreads. Na 'n week van eksperimentering, is hierdie opsie van die hand gewys weens die ingewikkeldheid van hoe hierdie uitbreiding werk. Na 'n maand van toetsing moes ek ook asinchroniese programmering in PHP laat vaar; Ek het iets eenvoudig nodig gehad, bekend aan enige PHP-beginner, en baie uitbreidings vir PHP is sinchronies.

Die oplossing was ons eie multi-threaded diens in C, wat saamgestel is met PHPLIB. Dit laai al die ATS php-lêers, wag vir al die modules om te inisialiseer, voeg 'n terugbel by mekaar, en wanneer alles gereed is, kas dit. By navraag deur FastAGI 'n stroom word geskep, 'n kopie van die kas van alle klasse en data word daarin gereproduseer, en die versoek word na die php-funksie oorgedra.

Met hierdie oplossing, die tyd vanaf die stuur van 'n oproep na ons diens tot die eerste opdrag asterisk afgeneem van 1,5s tot 0,05s en hierdie tyd hang effens af van die grootte van die projek.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Gevolglik is die tyd vir skakelplan-ontwikkeling aansienlik verminder, en ek kan dit waardeer aangesien ek die hele skakelplan van alle modules in PHP moes herskryf. Eerstens moet metodes reeds in php geskryf word om 'n voorwerp uit die databasis te verkry; dit was nodig om in die webkoppelvlak te vertoon, en tweedens, en dit is die belangrikste ding, is dit uiteindelik moontlik om gerieflik met stringe met getalle en skikkings te werk met databasis plus baie PHP uitbreidings.

Om die skakelplan in die moduleklas te verwerk, moet jy die funksie implementeer dialplanDynamicCall en argument pbxCallRequest sal 'n voorwerp bevat om mee te interaksie asterisk.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Daarbenewens het dit moontlik geword om die dialplan te ontfout (php het xdebug en dit werk vir ons diens), jy kan stap vir stap beweeg deur die waardes van veranderlikes te sien.

Bel data

Enige ontleding en verslae vereis korrek versamelde data, en hierdie PBX-blok het ook deur baie proef en fout van die eerste tot die derde weergawe gegaan. Dikwels is oproepdata 'n teken. Een oproep = een opname: wie het gebel, wie het geantwoord, hoe lank het hulle gepraat. In meer interessante opsies is daar 'n bykomende teken wat aandui watter PBX-werknemer tydens die oproep gebel is. Maar dit alles dek net 'n deel van die behoeftes.

Die aanvanklike vereistes was:

  • red nie net wie die PBX gebel het nie, maar ook wie geantwoord het, want daar is onderskeppings en dit sal in ag geneem moet word wanneer oproepe ontleed word,
  • tyd voor kontak met 'n werknemer. In GratisPBX en sommige ander PBX'e, word die oproep as beantwoord beskou sodra die PBX die telefoon optel. Maar vir die stemkieslys moet jy reeds die foon optel, so alle oproepe word beantwoord en die wagtyd vir 'n antwoord word 0-1 sekonde. Daarom is besluit om nie net die tyd voor 'n reaksie te bespaar nie, maar die tyd voor die verbinding met sleutelmodules (die module self stel hierdie vlag. Tans is dit "Werknemer", "Eksterne lyn").
  • vir 'n meer komplekse skakelplan, wanneer 'n oproep tussen verskillende groepe beweeg, was dit nodig om elke element afsonderlik te kan ondersoek.

Die beste opsie blyk te wees wanneer die PBX-modules inligting oor hulself op oproepe stuur en uiteindelik die inligting in die vorm van 'n boom stoor.

Dit lyk soos volg:

Eerstens, algemene inligting oor die oproep (soos almal anders - niks besonders nie).

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

  1. Het 'n oproep op 'n buitelyn ontvang "Vir die toets"om 05:55:52 vanaf die nommer 89295671458 na die nommer 89999999999, op die ou end is dit deur 'n werknemer beantwoord"Sekretaris 2» met nommer 104. Die kliënt het 60 sekondes gewag en 36 sekondes lank gepraat.
  2. Werknemer"Sekretaris 2"maak 'n oproep na 112 en 'n werknemer antwoord"Bestuurder 1» na 8 sekondes. Hulle praat vir 14 sekondes.
  3. Die kliënt word oorgedra na die werknemer "bestuurder 1" waar hulle vir nog 13 sekondes aanhou praat

Maar dit is die punt van die ysberg; vir elke rekord kan jy 'n gedetailleerde oproepgeskiedenis deur die PBX kry.

Die storie van een projek of hoe ek 7 jaar spandeer het om 'n PBX te skep gebaseer op Asterisk en Php

Alle inligting word aangebied as 'n nes van oproepe:

  1. Het 'n oproep op 'n buitelyn ontvang "Vir die toets» om 05:55:52 vanaf die nommer 89295671458 na die nommer 89999999999.
  2. Om 05:55:53 stuur die buitelyn 'n oproep na die Inkomende kring "toets»
  3. Wanneer 'n oproep volgens die skema verwerk word, sal die module "bestuurder oproep", waarin die oproep 16 sekondes is. Hierdie is 'n module wat vir die kliënt ontwikkel is.
  4. Module "bestuurder oproep" stuur 'n oproep na die werknemer verantwoordelik vir die nommer (kliënt) "Bestuurder 1” en wag 5 sekondes vir 'n antwoord. Die bestuurder het nie geantwoord nie.
  5. Module "bestuurder oproep"stuur 'n oproep na die groep"KORP bestuurders" Dit is ander bestuurders van dieselfde rigting (sit in dieselfde vertrek) en wag 11 sekondes vir 'n antwoord.
  6. Groep "KORP bestuurders"roep werknemers"Bestuurder 1, Bestuurder 2, Bestuurder 3"gelyktydig vir 11 sekondes. Geen antwoord.
  7. Die bestuurder se oproep eindig. En die kring stuur 'n oproep na die module "Kies 'n roete vanaf 1c" Ook 'n module geskryf vir die kliënt. Hier is die oproep vir 0 sekondes verwerk.
  8. Die kring stuur 'n oproep na die stemkieslys "Basies met bykomende skakelwerk" Die kliënt het 31 sekondes daar gewag, daar was geen bykomende skakeling nie.
  9. Die skema stuur 'n oproep na die Groep "Sekretarisse", waar die kliënt 12 sekondes gewag het.
  10. In 'n groep word 2 werknemers gelyktydig gebel "Sekretaris 1"En"Sekretaris 2"en na 12 sekondes antwoord die werknemer"Sekretaris 2" Die antwoord op die oproep word in oueroproepe gedupliseer. Dit blyk dat hy in die groep geantwoord het "Sekretaris 2", toe die kring bel geantwoord het"Sekretaris 2" en die oproep op die buitelyn beantwoord met "Sekretaris 2".

Dit is die stoor van inligting oor elke operasie en hul nes wat dit moontlik sal maak om bloot verslae te maak. ’n Verslag oor die stemkieslys sal jou help om uit te vind hoeveel dit help of belemmer. Stel 'n verslag saam oor oproepe wat deur werknemers gemis is, met inagneming dat die oproep onderskep is en dus nie as gemiste beskou word nie, en met inagneming dat dit 'n groepoproep was en iemand anders vroeër beantwoord het, wat beteken dat die oproep ook nie gemis is nie.

Sulke inligtingberging sal jou toelaat om elke groep afsonderlik te neem en te bepaal hoe effektief dit werk, en 'n grafiek te bou van beantwoorde en gemiste groepe per uur. Jy kan ook kyk hoe akkuraat die verbinding met die verantwoordelike bestuurder is deur die oordragte te ontleed nadat jy met die bestuurder verbind het.

Jy kan ook nogal atipiese studies doen, byvoorbeeld, hoe gereeld nommers wat nie in die databasis is nie die regte uitbreiding skakel of watter persentasie van uitgaande oproepe na 'n selfoon aangestuur word.

Die resultaat?

'n Spesialis word nie vereis om die PBX in stand te hou nie; die mees gewone administrateur kan dit doen - in die praktyk getoets.

Vir wysigings is spesialiste met ernstige kwalifikasies nie nodig nie; kennis van PHP is voldoende, want Modules is reeds geskryf vir die SIP-protokol, en vir die tou, en vir die oproep van 'n werknemer, en ander. Daar is 'n wikkelklas vir asterisk. Om 'n module te ontwikkel, kan 'n programmeerder (en moet op 'n goeie manier) klaargemaakte modules noem. En kennis asterisk is heeltemal onnodig as die kliënt vra om 'n bladsy met 'n nuwe verslag by te voeg. Maar die praktyk toon dat alhoewel derdepartyprogrammeerders dit kan hanteer, voel hulle onseker sonder dokumentasie en normale dekking van kommentaar, so daar is nog ruimte vir verbetering.

Modules kan:

  • skep nuwe oproepverwerkingsvermoëns,
  • voeg nuwe blokke by die webkoppelvlak,
  • erf van enige van die bestaande modules, herdefinieer funksies en vervang dit, of wees bloot 'n effens gewysigde kopie,
  • voeg jou instellings by die instellingssjabloon van ander modules en nog baie meer.

PBX-instellings via API. Soos hierbo beskryf, word alle instellings in die databasis gestoor en gelees ten tyde van die oproep, sodat jy alle PBX-instellings deur die API kan verander. Wanneer die API geroep word, word die konfigurasie nie herskep nie en die modules word nie herbegin nie, daarom maak dit nie saak hoeveel instellings en werknemers jy het nie. API-versoeke word vinnig uitgevoer en blokkeer mekaar nie.

Die PBX stoor alle sleutelbewerkings met oproepe met tydsduur (wag/gesprek), nes en in PBX-terme (werknemer, groep, eksterne lyn, nie kanaal, nommer). Dit laat jou toe om verskeie verslae vir spesifieke kliënte te bou en die meeste van die werk is om 'n gebruikersvriendelike koppelvlak te skep.

Tyd sal leer wat volgende gaan gebeur. Daar is nog baie nuanses wat oorgedoen moet word, daar is nog baie planne, maar 'n jaar het verloop sedert die skepping van die 3de weergawe en ons kan reeds sê dat die idee werk. Die grootste nadeel van weergawe 3 is die hardeware hulpbronne, maar dit is gewoonlik waarvoor jy moet betaal vir die gemak van ontwikkeling.

Bron: will.com

Voeg 'n opmerking