Asenkron İşlemler


    × Bunları biliyor muydunuz?
".htaccess dosyasının içeriğini yapılandırmak için Settings/Htaccess.php yapılandırma dosyası kullanılır."


Bu kütüphane bekleme gerektiren işlemleri arkaplanda ( Commands/ ) çalıştırarak ön tarafta herhangi bir geçikmeye neden olmadan kodların işlenmesini sağlar. Özellikle e-posta gönderimi, döngüsel işlemler, big data gibi geçikmeye neden olabilecek işlemler için kullanışlıdır. Çalışma mekanizması Commands/ dizini içerisinde geliştirilen sınıflara 'SınıfAdı:yöntemAdı' söz diziminde istek gönderilerek gerçekleşir. Bu istek gönderiminden sonra kod akışı kaldığı yerden devam ederken istek gönderilen tarafta kodlar işlemeye başlar. Bu kodların işlenmesinde geçen süre kullanıcı tarafına yansıtılmaz. Bu süreçte bir çalıştırma dosyası oluşturulur ve bu dosyanın içerisinde çalışan işleme ait veriler ile ön taraftan gönderilen veriler yer alır. Bu dosya işlem tamamlanıncaya kadar var olmaya devam eder. İşlem başarılı bir şekilde tamamlandıktan sonra oluşturulan bu dosya kendiliğinden silinir. Bu işlem dosyaları ön tanımlı olarak FILES_DIR dizinine kaydedilir. Böyle bir dosyayı var etmenin amacı ön taraftan arka tarafa data veya parametre gönderebilmektir. Gönderilen datalar bir dosyaya yazılarak tutulduğundan scalar (ölçeklenebilir) olmak zorundadır. Herhangi bir şekilde callable ve resource türünden data göderimi mümkün değildir. Bu sınıfın kullanımını gerektiren bir kod yazılıyorsa mutlaka kod ağırlığı mümkün mertebe arka tarafta olmalıdır. Commands/ tarafında başlangıç kontrolcü ve dosyalarının devre dışı kaldığı unutulmamalıdır. Başlangıç dosyalarında yer alan ayarlar ve fonksiyonlar arka tarafta da kullanılmak isteniyorsa komut kütüphanelerine require ile dahil edilebilir. Başlangıç kotrolcüleri ie new ile veya statik olarak tanımlanmışsa Initialize::main() gibi kullanılarak dahil edilebilir. Bunlar dışında arkaplanda ZN'ye ait tüm kütüphaneler sorunsuzca kullanılabilir.

 

 

# Kurulum


ZN dağıtımları için terminal kurulum komutu. Bu sınıf Console kütüphanesi ile beraber gelmektedir.

↓ composer require znframework/package-console

 

 

# Örnek Uygulamalar


# SMS Gönderimi

 

 

# Yöntemler


Async::setProcDirectory(string $directory) : this
Async::run(string $command, array $data) : string
Async::process(string $procId, callable $callable, bool $displayError = false) : void
Async::loop(int $count, int $waitSecond, callable $callback) : void
Async::close(string $procId = '') : string|false
Async::closeAll() : void
Async::getData(string $procId = '') : array
Async::isExists(string $procId = '') : bool
Async::isRun(string $procId = '') : bool
Async::remove(string $procId = '') : bool
Async::list() : array
Async::report(array $data = []) : int
Async::status(string ...$procIds) : array
Async::isFinish(string ...$procIds) : bool
Async::getProcId() : string
Async::displayError(string $errorFile) : string

 

# Dinleme Yöntemleri [8.16.0][2024-08-23]


Async::setSocketURI(string $URI) : this
Async::socket() : exit
Async::output(array $data) : int
Async::listen(string $procId, int $millisecond= 1000) : script

 

 

# SetProcDirectory [8.3.0][2023-06-15]


İşlem dosyaları ($procId) varsayılan olarak FILES_DIR sabitinin gösterdiği konuma ( Projects/Frontend/Resources/Files/ ) kaydedilir. Bunu değiştirmek için bu yöntemden yararlanılır. Bu yöntemin başlangıç kontrolcüsünde kullanılması önerilir. Tüm veri akışı işlem dosyaları üzerinden yürütüldüğünden bu dosyaların konumu önemlidir.

string $location
Hata içeriği gösterilecek işlemin hata dosyası adı.
return this
Dosya: Controllers/Initialize.php
public function main()
{
    Async::setProcDirectory(STORAGE_DIR . '/procs/');
}

Yukarıda yer alan örneğe göre artık ilgili işlem dosyalarının yolu Projects/Frontend/Storage/Files/procs/ dizini olacaktır.

 

 

# Run  [8.3.0][2023-06-15]


Commands/ klasörüne yazılmış komut kütüphanelerine çalıştırma isteği gönderir. 

string $command
Çalıştırılacak Commands/Command.php dosyası.
array $data = []
İlgili komut kütüphanesine gönderilecek datalar. Gönderilecek datalar scalar|array türden olabilir. Gönderilen datalar bir dosya üzerine yazıldığından callable vb. türde verilerin gönderilebilmesi mümkün değildir.
string $procId = ''
[8.14.0][2024-08-14] İlgili işlem dosyasına isim verilebilir. Herhangi bir parametre belirtilmezse uniqid() yönteminin oluşturacağı bir değer dosya ismi olarak kullanılır. Bir komut kütüphanesinin birden fazla kullanıcı tarafından tetiklenme durumu varsa bu değerin varsayılan olarak bırakılması en doğru seçenektir. Ya da kullanıcı adı veya ID bilgisi de tercih edilebilir.
return string
İstek sonrası oluşan işlem dosyasının yolunu döndürür. Dönen veri Projects/Frontend/Resources/Files/64d20043cecbf dizimine benzer eşsiz bir dosya adıdır.
Dosya: Controllers/Example.php

Çalıştırılacak komut kütüphanesi Commands/ dizininde yer alan sınıflardır. Bu sınıflara ait yöntemlere atılan istek 'SınıfAdı:yöntemAdı' şeklinde olmalıdır. İstek oluşturulduktan sonra data gönderimi amacıyla bir işlem dosyası oluşur ve bu dosyanın adı sistem tarafından $procId adında bir parametreyle gönderilir. Bu $procId bilgisini gönderilen verilerin kaydedildiği işlem dosyasından veri almak için kullanacağız. 

public function main()
{
    $procId = Async::run('SendMail:run',
    [
        'email'   => '[email protected]',
        'title'   => 'Example',
        'content' => 'Example Content'
    ]);
}

Yukarıdaki örnekte Commands/SendMail.php sınıfı içerisinde yer alan run() yöntemine istek atmış olduk. Bu istekle beraber arkplanda ihtiyaç duyacağımız E-posta gönderimi için gereken 'email', 'title' ve 'content' isimli verileri array $data parametresi ile gönderdik.

Uyarı: Config/Services.php:processor->path yapılandırması değiştirilmediği sürece komut sunucunun php'si üzeride yürütülür. Herhangi bir yapılandırma sorunu yaşanmaması için bu yolu mevcut php(c:\\php\php.exe) ile değiştirmek gerekebilir.

string $procId = '' [8.14.0][2024-08-14]

Bu parametre ile oluşan process dosyasının adı değiştirilebilir. Bilinen bir isim kullanılması kodun devamında kullanım kolaylığı sağlar. Dikkat edilmesi gereken aynı komutun birden fazla kullanıcı tarafından tetiklenmesi ihtimali varsa kullanıcıya göre değişebilen isimlerin kullanılması gerekir.

public function main()
{
    $procId = Async::run('SendMail:run',
    [
        'email'   => '[email protected]',
        'title'   => 'Example',
        'content' => 'Example Content'
    ], UNAME . '-mail');
}

Yukarıdaki kodda UNAME kullanıcı adını tutan örnek bir sabit olarak kullanılmıştır.

 

 

# Process [8.3.0][2023-06-15]


Bu yöntem, çalıştırılacak kodları barındıracak şekilde Commands/ komut kütüphanelerine ait yöntemlerin içine yazılarak kullanılır. Callable bir yapıya sahipttir ve kendi içerisinde çeşitli işlemler gerçekleşir. Bu nedenle bu yöntemi mutlaka kullanmaya özen gösteriniz.

string $procId
Bu prametre komut kütüphanesinin yönteminin 1. parametresinde saklanır ve olduğu gibi kullanılır. O nedenle bu parametre ile ilgili herhangi bir başka işlem yapılmaz.
callable $callable Çalıştırılacak kodların yazılacağı parametre.
bool $displayError = false
[8.5.0][2023-08-08] Arkaplanda yürütme isteği sonrası oluşabilecek hataların {procId}-error formatında bir dosyaya yazılıp yazılmayacağı. Bu değerin true olarak ayarlanması oluşan hataların daha kolay farkedilmesi adına tavsiye edilir.
Dosya: Commands/SendMail.php
# $procId o an yapılan isteğe ait verileri tutan işlem dosyasıdır.
# Bu veri sistem tarafından gönderilir.
public function run($procId)
{
    Async::process($procId, function($data)
    {
         Email::to($data['email'])->send($data['title'], $data['content']);
    });
}

Yukarıdaki örnekte bir önceki örnek kullanımda gösterilen Async::run() yöntemi ile gönderilen datalara nasıl erişildiği ve kullanıldığı gösterilmiştir.

Bilgi:  $data parametresi içerisinden gönderilen verilerle beraber işlemin durumu ile ilgili 'status' anahtarlı bir durum dizisi saklar.  
Uyarı: $procId eşsiz gönderilen verilerin saklandığı işlem anahtarı veya dosyasıdır. Her bir isteğe ait işlemlerin bir birinden ayrılması için gereklidir. 
Dikkat: Komut kütüphanelerinin çalışması esnasında Starting dosyaları ve Başlangıç kontrolcüleri devreye girmez. Bu nedenle e-posta ve veritabanı gibi ayarlar eğer başlangıç kontrolcüsünde tanımlanmışsa kontrolcünün çağırılması şeklinde ya da ilgili komut kütüphanesinde  yapılandırılacak şekilde kullanılmalıdır.

bool $displayError = false [8.5.0][2023-08-08]

Async::process() yönteminin 3. parametresinin true olarak ayarlanması durumunda arkaplanda çalışan kod üzerinde oluşan denetlenebilir hataların  procId-error dosyasına yazılmasını sağlar. Böylece hatanın neyden kaynaklandığının tespitinde kolaylık sağlanmış olur.

Önemli: Bu yöntem sorunsuz bir şekilde çalışırsa Async::run() ile oluşan işlem dosyası kendiliğinden silinir. Silinmemişse işlem devam ediyor demektir.

 

 

# Loop [8.14.0][2024-08-14]


Arkaplanda çalışacak işlerin bir döngü içerisinde sürekli çalışmaya devam etmesi istenebilir. Bu durumda while gibi kendi döngülerinizi kullanabileceğiniz gibi daha kısa bir şekilde döngü oluşturmanızı sağlayan bu yöntemi de kullanabilirsiniz.

int $count
Döngünün kaç kez döneceği. Sürekli dönmesi isteniyorsa -1 gibi negatif bir değer kullanılabilir.
int $waitSecond Döngünün kaç saniye aralıklarla döneceğidir. Örnek: 5 olması durumunda her 5 saniyede bir döngü dönmeye devam edecektir
callable $callable
Çalıştırılacak kodların yazılacağı parametre.
return void
Dosya: Commands/Cron.php
namespace Project\Commands;

use Async;
use Currency;

class Cron extends Command
{
   public function updateCurrencies($procId)
   {
      Async::process($procId, function($data)
      {
         # Her saatte 1 kontrol et
         Async::loop(-1, 3600, function()
         {
            # Para birimlerine ait değerleri güncelle.
            Currency::update();
         });

      }, true);
   }
}

Yukarıdaki örnekte her saatte bir para birimlerinin güncel değerlerini çeken kod yazmış olduk. int $count = -1 kullanımı sebebiyle döngü sürekli olarak devam edecektir.

 

 

# Close [8.14.0][2024-08-14]


Asenkron işlemlerde Commands/ tarafında işlemleri kapatmanız gerekmez. Bu işlem kendiliğinden gerçekleşir. Ancak döngü içeren veya uzun süreli çalışması gereken işlemlerin sonlandırılmasında kullanılabilir. Çünkü devam eden işlem bitmediğinden otomatik olarak kapatılamayacaktır. İşlemin kapatılmasıyla beraber işlem doyası da silinir.

string $procId = ''
Async::run() ile oluşturulan ve durdurulmak istenen işlem dosyası.
return string|false
Dosya: Controllers/Cron.php
namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function startUpdateCurrencies()
   {
        Async::run('Cron:updateCurrencies', [], 'updateCurrencies');
   }

   public function stopUpdateCurrencies()
   {
        Async::close('updateCurrencies');
   }
}

Yukarıdaki örnekte Async::run() ile tetiklenen 3. parametresi 'updateCurrencies' olarak belirlenmiş bir işlemin nasıl durdurulduğu gösterilmiştir.

 

 

# CloseAll [8.14.0][2024-08-14]


Devam eden işlemlerin tümünü sonlandırır.

return void

Dosya: Controllers/Cron.php

namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function stopAll()
   {
        Async::closeAll();
   }
}

 

 

# GetData [8.3.0][2023-06-15]


İşlem dosyasına yazılan verileri dizi formunda almak için kullanılır. Normalde Async::process() yöntemi içerisinde bu veriler $data değişkeni ile gelmektedir. Ancak bazı durumlarda devam eden işlemle ilgili verilerin alınmasında kullanılabilir.

string $procId = ''
Verilerin alınacağı işlem dosyasının adı.
return array
Dosya: Controllers/Cron.php
public function main()
{
    output(Async::getData('updateCurrencies'));
}
status => 
[
        command  => 'php zerocore Cron:updateCurrencies ...',
        pid      => 11732,
        running  => true,
        signaled => false,
        stopped  => false,
        exitcode => -1,
        termsig  => 0,
        stopsig  => 0,
        run      => 'Cron:updateCurrencies',
        file     => 'updateCurrencies',
        path     => 'assets/procs/UpdateCurrencies'
],
exampleKey1 => exampleValue1,
exampleKey2 => exampleValue2,
...

 

 

# IsExists [8.14.0][2024-08-14]


Devam eden işlem dosyasının fiziksel olarak var olup olmadığını kontrol eder.

string $procId = ''
Async::run() ile oluşturulan işlem dosyası.
return bool
Dosya: Controllers/Cron.php
namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function main()
   {
        if( Async::isExists('updateCurrencies') )
        {
            # kodlar...
        }
   }
}

 

 

# IsRun [8.14.0][2024-08-14]


İşlem dosyasının işlenmeye devam edip etmediğini kontrol eder.

string $procId = ''
Async::run() ile oluşturulan işlem dosyası.
return bool
Dosya: Controllers/Cron.php
namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function main()
   {
        if( Async::isRun('updateCurrencies') )
        {
            # kodlar...
        }
   }
}

 

 

# Remove [8.14.0][2024-08-14]


Async::close() yönteminden farklı olarak sadece işlem dosyasını fiziksel olarak silmek için kullanılır. Eğer dosya arkaplanda işlenmeye devam ediyorsa işlemi sonlandırmadan sadece işlem dosyasını silecektir.

string $procId = ''
Async::run() ile oluşturulan işlem dosyası.
return bool
Dosya: Controllers/Cron.php
namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function main()
   {
        Async::remove('updateCurrencies');
   }
}

 

 

# List [8.14.0][2024-08-14]


Devam eden işlemlerin tümünü sonlandırır.

return array

Dosya: Controllers/Cron.php

namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function main()
   {
        output(Async::list());
   }
}
=> 
[
    status =>
    [
        command  => 'php zerocore Cron:updateCurrencies',
        pid      => 7728,
        running  => true,
        signaled => false,
        stopped  => false,
        exitcode => -1,
        termsig  => 0,
        stopsig  => 0,
        run      => 'Cron:updateCurrencies',
        file     => 'UpdateCurrencies',
        path     => 'assets/procs/UpdateCurrencies'
    ]
]

 

 

# Report [8.3.0][2023-06-15]


Arkaplanda çalışan kodlarda gerçekleşen istisnai durumları raporlamak için kullanılır. Bu yöntemin kullanımı ile işlem dizinine $procId-report adında rapor dosyası oluşturulur.

array $data
Rapor dosyasına yazdırılacak veriler.
return int
Dosya: Commands/Cron.php
public function updateCurrencies($procId)
{
    Async::process($procId, function($data)
    {
         if( ! Currency::update() )
         {
             Async::report(['error' => 'Kurlar güncellenemedi!']);
         }
    });
}
Oluşturulan Dosya: updateCurrencies-report

 

 

# Status [8.3.0][2023-06-15]


İşlem $procId değerlerine göre işlemi devam edenleri dizi türünde döndür. Yani fiziksel olarak bulunan işlem dosyalarını listeler.

string ...$procId
Durumu kontrol edilecek işlem ID veya ID'ler.
return array Durumu devam eden işlemleri [$file1 => 1, $file2 => 1] biçiminde gösteren dizi döndürür.

Dosya: Controllers/Cron.php

public function status()
{
    $status = Async::status('sendMail', 'updateCurrencies'); 

    output( $status )
}

$status işlemi devam edenleri listeyelen aşağıdaki gibi bir dizi üretir.

[
    'updateCurrencies' => 1
]

Yukarıdaki çıktıda 'sendMail' işleminin tamamlandığı ancak 'updateCurrencies' işleminin devam ettiği anlaşılır.  

 

 

# IsFinish [8.3.0][2023-06-15]


İşlem ID'lerine göre işlemlerin bitip bitmediğini döndürür. İşlemlerin hepsi bitmişse true en az biri bile bitmemişse false değeri döndürür.

string ...$procId
Durumu kontrol edilecek işlem ID veya ID'ler.
return bool Durumu devam eden işlem varsa false yoksa true türünde değer döndürür.

Dosya: Controllers/Cron.php

public function isFinish()
{
    if( Async::isFinish('sendMail', 'updateCurrencies') )
    {
        # Belirtilen işlemlerin tümü biterse...
    }
}

 

 

# GetProcId [8.3.0][2023-06-15]


Async::run() veya Async::process() yöntemlerinden sonra oluşan işlem dosyasınının yolunu verir.

return string

Dosya: Controllers/Cron.php

namespace Project\Controllers;

use Async;

class Cron extends Controller
{
   public function run()
   {
        Async::run('Cron:updateCurrencies', ['myData' => 5], 'updateCurrencies');

        output( Async::getProcId() );
   }
}
Projects/Frontend/Storage/procs/updateCurrencies

 

 

# DisplayError [8.6.0][2023-08-08]


Async::process() yönteminin 3. parametresi $displayError = true olarak kullanılan işlemlerde gerçekleşen hatalar '{procId}-error' görünümünde dosyalara yazılır. Bu yöntem, dosyalara yazılmış hataların ZN'nin standart hata görüntüleme aracında görüntülenmesini sağlar.

string $errorFile
Hata içeriği gösterilecek işlemin hata dosyası adı.
return string Hata içeriği.

Dosya: Controllers/DisplayError.php

public function main()
{
    $errorFile = '64d20043cecbf-error';

    echo Async::displayError($errorFile); 

    exit;
}

Yukarıda yer alan örnekteki gibi bir kontrolcü yardımı ile ilgili hata dosyasının görüntülenmesini sağlayabilirsiniz.

 

 

# Dinleyici Oluşturmak [8.16.0][2024-08-23]


Commands/ tarafında çalışan kodların işlem bittiğinde durumu hakkında bilgi almak için tasarlamış yöntemlerdir. Örneğin bir E-posta gönderimi veya SMS gönderiminde herhangi bir hata alınmasa dahi bu isteklerin gerçekleşip gerçekleşmediğinin kontrol edilmesi gerekir. İşte bu yöntemler bu süreci yönetmek ve kontrol etmek için geliştirilmişlerdir. Bu yöntemler AJAX ile gerçekleştirildiğinden gerçek bir soket işlemi yürütülmemektedir. Sadece soket işlemini simüle etmektedir.

Gereklilikler

jQuery

 

 

# SetSocketURI [8.16.0][2024-08-23]


Commands/ tarafında gerçekleşen işlemlerin durumu hakkında bilgi almak için dinleme soketinin konumunu belirtir. Bu yöntem sadece 1 kez kullanılacağından Başlangıç Kontrolcüsünde (Initialize) kullanılmadır.

string $URI
Async::socket() yönteminin yerleştirileceği URI bilgisi.
return this
Dosya: Controllers/Initialize.php
public function main()
{
    Async::setSocketURI('Home/socket');
}

Yukarıda yer alan örneğe göre Home/socket adresi arkaplan işlemlerinin durumunlarını dinlemek için kullanacağımız kontrolcü ve yöntemdir.

 

 

# Socket [8.16.0][2024-08-23]


Dinleme yapmak üzere soket oluşturur. Async::setSocketURI() yöntemi ile belirlenmiş URI'a bu yöntem yerleştirilir. Bu yöntem satır sonunda exit deyimi içerir.

return exit
Dosya: Controllers/Home.php
public function socket() : void
{
    Async::socket();
}

Yukarıdaki örnekte görüldüğü gibi sadece Async::socket() yöntemi kullanılır ve farklı işlem yapılmaz. Bu yöntem exit içerdiğinden sonrasına kod yazılamaz.

 

 

# Output [8.16.0][2024-08-23]


Commands/ tarafından ön tarafa Async::listen() yönteminde kullanmak üzere veri döndürür. 

array $data
Döndürelecek veriler. Veriler scalar olmak zorundadır.
return int
Dosya: Commands/SendEmail.php
public function run($procId)
{
    Async::process($procId, function($data)
    {
         try
         {
             $status = Email::to($data['email'])->send($data['title'], $data['content']);
         }
         catch( Exception $e )
         {
             $error = $e->getMessage();
         }

         Async::output(['isEmail' => $status, 'email' => $data['email'], 'error' => $error]);
    });
}

Yukarıdaki örnekte E-posta gönderiminin true veya false olan sonucunu döndürdük. Bu dizi ile dönen anahtarlar Async::listen() yöntemi ile konrol edilmek amacıyla kullanılır.

 

 

# Listen [8.16.0][2024-08-23]


Bu yöntem $procId bilgilerine göre dinleme yapar. Arkaplanda gerçekleşen işlemler sonucu dönen değerlere göre işlem yapar.

string $procId
Dinlenilmek istenen işlem dosyası. Bu parametre doğrudan PHP tarafından değilde bir AJAX isteği sonrası gelen veri ile set edilecekse Async::listen({< parametre >}) gibi kullanımalıdır.
int $millisecond = 1000
Kaç milisaniyede bir dinleme isteği gönderileceğidir. Varsayılan 1000 milisaniyedir yani 1 saniye.
return this

Parametrik Yöntemler

Async::success(callable $callback) : this
Async::error(callable $callback) : this

Öncelikle komut çalıştırma kodumuzu yazalım. Example adında örnek bir kontrolcümüzün ve send() yönteminde e-posta gönderimiyle ilgili komut dosyasına çalıştırma isteği göndereceğimiz kodlar olduğunu varsayalım.

Dosya: Controllers/Example.php
public function send()
{
    $procId = Async::run('SendEmail:run',
    [
        'email'   => '[email protected]',
        'title'   => 'Example',
        'content' => 'Example Content'

    ]);

    View::sendEmailProcId( $procId );
}

Yukarıdaki örnekte SendMail:run komut dosyasına çalıştırma isteği gönderdik. Ve işlem dosyasını View::sendEmailProcId() yönteminde tuttuk. Bu veriyi Async::listen() ile dinleme yapmak için kullanacağız.

Şimdi de yukarıdaki kontrolcümüze ait örnek bir görünüm oluşturalım.

Dosya: Views/Example/send.wizard.php
<span id="sendEmailStatus">E-posta gönderimi</span>
<script>
@Async::success
({<
    // Async::output() ile döndürdüğümüz isEmail anahtarı.
    if( data.isEmail ) 
    {
        $('#sendEmailStatus').html(data.email + ' adresine e-posta gönderildi.');
    }
    // işlem devam ederken sistem {status: processing} döndürür.
    else if( data.status == 'processing' )
    {
        $('#sendEmailStatus').html('E-posta gönderiliyor...');
    } 
    // Async::output() ile döndürdüğümüz error anahtarı.
    else if( data.error )
    {
        $('#sendEmailStatus').html('E-posta gönderilemedi! Hata: ' + data.error);
    } 
>})::listen( View::sendEmailProcId() )
</script>

Yukarıdaki kod Async::setSocketURI() yöntemi ile belirlenmiş Home/socket adresini dinler. Daha sonra Async::output() ile oluşturulmuş dataya bakmaya başlar. Verinin bulunması halinde istek göndermeyi bırakır.

Bilgi: Async::listen() yöntemini isterseniz javascript fonksiyonları içerisinde olaylar (events) ile çalışacak şekilde de kullanabilirsiniz.
Bilgi: İstek sonrası sayfadan çıkılması durumunda işlemlerin durumu hakkında dinleme yapmaya devam etmek isterseniz $procId bilgisini View:: yerine Session:: da saklayınız.

 

 

# Örnek SMS Gönderimi


Aşağıda örnek SMS gönderimi için aşamalar yer almaktadır.

1 - Soketi Konumlandırın
Dosya: Controllers/Initialize.php
public function main()
{
    # Dinleme isteklerinin belirtilen konuma yapılmasını sağlar.
    Async::setSocketURI('Initialize/socket');
}

public function socket() : void
{
    # Dinleme isteklerine yanıt verir.
    Async::socket();
}
2 - Çalıştırılacak Komut Dosyasını Hazırlayın
Dosya: Commands/SMS.php
<?php namespace Project\Commands;

use CURL;
use Async;

class SMS extends Command
{
   public function send($procId)
   {
      Async::process($procId, function($data)
      {
         $error   = false;
         $url     = 'http://g3.{provider}.com';
         $content = '<MultiTextSMS>
                       <UserName>{userName}</UserName>
                       <PassWord>{password}</PassWord>
                       <Action>1</Action>
                       <Messages>
                         <Message>
                           <Mesgbody>' . $data['message'] . '</Mesgbody>
                           <Number>' . $data['phone'] . '</Number>
                         </Message>
                       </Messages>
                       <Originator>{originator}</Originator>
                     </MultiTextSMS>';
        
         $send = CURL::init()
            ->option('url', $url)
            ->option('returntransfer', true)
            ->option('followlocation', true)
            ->option('postfields', $content)
            ->option('httpheader', ["Content-Type: text/plain"])
            ->exec();

         if( CURL::errno() ) 
         {
             $error = CURL::errno();
         }

         $isSend = strstr($send, 'ID') ? true : false;

         # Async::listen() yönteminde kullanılmak üzere sonuçları döndürüyoruz.
         Async::output(['isSend' => $isSend, 'error' => $error]);
         
      }, true);
   }
}
3 - İstek Yapılacak Kontrolcüyü Hazırlayın
Dosya: Controllers/Home.php
<?php namespace Model\Home\Controllers;

use Async;

class Home
{
    public static function main()
    {
       
    }

    public static function ajaxSendSMS() : void
    { 
        $procId = Async::run('SMS:send',
        [
            'phone'   => '0555.......',
            'message' => 'Bu bir test mesajıdır!'
        ]);    
    
        echo json_encode(['procId' => $procId]);
    }
}
4 - Görünümü Hazırlayın
Dosya: Views/Home/main.wizard.php
<span id="status"></span>

<a onclick="ajaxSendSMS()">Mesaj Gönder</a>

<script>

function ajaxSendSMS()
{
    @ajax('Home/ajaxSendSMS')->dataType('json')->success
    ({<
        @Async::success
        ({<
            if( data.status == 'processing' )
            {
                $('#status').html('SMS gönderiliyor...');
            }
            else if( data.isSend )
            {
                $('#status').html('SMS gönderildi.');
            }
            else
            {
                $('#status').html('SMS gönderilemedi! Hata:' + data.error);
            }

        >})::listen({< data.procId >})    
    >})
}

</script>