Perusahaan saya menggunakan sistem telepon Cisco. Sistem ini mencatat semua riwayat telepon dan status agen dalam database sql. Saya telah ditugaskan untuk mengambil data ini, dan menampilkannya secara realtime di situs web sehingga seluruh perusahaan dapat melihat status semua pekerja saat ini (mis. dalam panggilan, tidak siap, dalam rapat, lama panggilan saat ini, saat istirahat, dll) dengan gaya GUI. Saya tahu saya dapat menulis kueri untuk mendapatkan data ini, tetapi saya ingin mengetahui pendekatan terbaik untuk menampilkan data ini dan memperbaruinya secara waktu nyata tanpa penyegaran halaman dan memperbarui data saat itu terjadi
MANTAN. Pengguna mendapat panggilan pada 12. 00 WIB, status user berubah dari idle menjadi aktif. Avatar pengguna akan berubah dari abu-abu (idle) menjadi hijau (aktif) Pengatur waktu kemudian akan mulai menghitung berapa lama pengguna dalam panggilan. Setelah 8 menit, pengguna mengakhiri panggilan dan kemudian pergi makan siang, sehingga avatar pengguna akan berubah dari hijau (aktif) menjadi merah (tidak aktif)
Ada 50 agen yang semuanya akan ditampilkan di layar yang sama. Saya perlu menemukan cara untuk merampingkan ini sebanyak mungkin, dan memperbarui status sesering mungkin. Saya telah melihat jquery, dan program ajax lainnya, tapi saya agak mencari contoh kerja yang bisa saya tiru
Informasi apa pun yang dapat Anda berikan kepada saya, tutorial, atau kode, akan sangat dihargai. Saya memiliki skema database untuk data jika diperlukan
Posting ini adalah sekumpulan pendekatan dan aturan yang digunakan SmartGamma untuk membangun aplikasi web real-time. Solusi waktu nyata kami sebagian besar didasarkan pada artikel dan rekomendasi dari Phil Leggetter — penginjil dan konsultan web waktu nyata. Artikel-artikelnya memberi kita pemahaman yang sangat jelas tentang teknologi web waktu nyata yang dapat kita gunakan untuk membangun aplikasi waktu nyata tersebut
Apa itu waktu nyata?
Web real-time adalah seperangkat teknologi dan praktik yang memungkinkan pengguna untuk menerima informasi segera setelah dipublikasikan oleh pembuatnya, daripada mengharuskan mereka atau perangkat lunak mereka memeriksa sumber secara berkala untuk pembaruan. (wikipedia)
Secara teoritis ini berarti "pengiriman data segera". Namun, secara praktis data harus disampaikan dalam periode yang relevan dan periode ini selalu bergantung pada konteks. Momen penting lainnya di sini adalah mengirimkan data tanpa permintaan reguler oleh server dari sisi klien
Mekanisme transportasi
Secara teknis kami memiliki beberapa mekanisme transportasi untuk menyediakan koneksi waktu-nyata atau yang disebut koneksi “hampir waktu-nyata”.
- Polling panjang HTTP — klien melakukan polling ke server yang meminta informasi baru. Server menahan permintaan terbuka sampai data baru tersedia. Setelah tersedia, server merespons dengan data baru dan koneksi terputus. Ketika klien menerima respons, segera mengirimkan permintaan lain, dan operasi diulangi
- Streaming HTTP — berdasarkan koneksi terus-menerus antara klien dan server. Jadi ketika server memiliki data baru, server dapat mendorongnya ke klien
- HTML5 WebSockets (RFC6455) — ini adalah spesifikasi yang memungkinkan komunikasi dua arah antara klien dan server melalui satu koneksi TCP. Ini awalnya dibuat untuk browser web, tetapi dapat digunakan pada klien mana pun yang dapat menangani koneksi TCP
Mengapa kami memutuskan untuk memilih WebSockets?
- Keuntungan utama dari soket web adalah bukan permintaan HTTP, setelah permintaan jabat tangan awal, satu koneksi TCP dibuat dan itu ada selama yang kita butuhkan. Kita tidak perlu mengirimkan header pada setiap pesan — jadi tidak ada overhead, hanya data
- Sangat efisien jika aplikasi sering membutuhkan pertukaran data dalam dua arah. Ini berarti klien dan server mengirimkan data dalam satu koneksi. Dengan kata lain itu benar-benar dua arah
- Sejumlah besar klien memungkinkan untuk mengimplementasikan klien pada bahasa apa pun
- Dapat digunakan dengan enkripsi SSL — wss. // URL, itu wajib dalam persyaratan aplikasi kami
WebSocket dengan PHP
Di salah satu proyek streaming video langsung Symfony2 kami, kami memiliki persyaratan untuk membangun interaksi waktu nyata antara pengguna — semacam obrolan. Jadi kami mulai belajar bagaimana itu bisa diterapkan. Pertama kami menemukan perpustakaan Ratchet oleh Chris Boden (GitHub). Pustaka ini mengimplementasikan server WebSocket di atas ReactPHP. Itu dapat dengan mudah dimasukkan ke dalam perintah konsol Symfony (ditemukan di sini) yang berjalan dalam loop reaksi tak terbatas
Jadi inilah beberapa contoh kode implementasi kami. Pertama-tama perintah konsol Symfony untuk menjalankan server
class ListenCommand extends ContainerAwareCommand{
protected function configure()
{
$this
->setName('websocket:listen')
->setDescription('Listen for websocket')
->addOption('port', 'p', InputOption::VALUE_REQUIRED, 'The port to listen on', 8000)
->addOption('interface', 'i', InputOption::VALUE_REQUIRED, 'The interface to listen on', '0.0.0.0')
;
}protected function execute(InputInterface $input, OutputInterface $output)
{
$application = new WebSocketApplication(
$this->getContainer()->get('snc_redis.default'),
$this->getContainer()->get('doctrine.orm.entity_manager'),
);
$server = IoServer::factory(
new HttpServer(
new WsServer(
new SessionProvider(
$application,
new RedisSessionHandler($redis)
)
)
),
$input->getOption('port'),
$input->getOption('interface')
);$output->writeln(sprintf('Listening on: %s:%s', $input->getOption('interface'), $input->getOption('port')));$server->run();
}
}
Terlihat jelas dan sederhana. Kelas WebSocketApplication harus mengimplementasikan MessageComponentInterface yang disediakan oleh Ratchet. Ini berisi metode onOpen, onClose, onMessage dan onError. Yang terpenting di sini adalah metode onMessage dan berikut tampilannya di aplikasi kita
public function onMessage(ConnectionInterface $from, $msg){
$messageData = $this->decodeJSONAndCheckMessage($from, $msg);
if (!$messageData) {
return;
}
$loginResult = $this->deviceLogin($from, $messageData);if (!$loginResult instanceof Error) {
$this->handleMessage($from, $messageData, $loginResult);
} else {
$this->onError($from, new \Exception('Cannot login device.'));
}
}_
Di sini kami memproses pesan masuk sebagai string JSON dan meneruskan data ke metode handleMessage()
private function handleMessage(ConnectionInterface $from, stdClass $messageData){
$message = $messageData->message;
if (method_exists($this, $message)) {
try {
$this->$message($from, $messageData);
}
} catch (\Exception $ex) {
$this->onError($from, $ex);
}
} else {
$this->onError($from, new \Exception(sprintf('Unknown method "%s"', $message)));
}
}
Jadi itu hanya memanggil metode yang berasal dari pesan websocket ($messageData->message) dan meneruskan objek ConnectionIntreface jika kita perlu merespons dengan beberapa data ke klien. Ini adalah contoh yang disederhanakan, tetapi ini menunjukkan dasar-dasar cara menangani websocket dengan PHP dan Symfony2. Tentu saja kami memiliki banyak logika aplikasi di kelas WebSocketApplication
Pro
1. Tidak sulit untuk mengimplementasikan aplikasi websocket dengan Ratchet. Kami menggunakannya dalam produksi dan berfungsi dengan baik untuk jangka waktu yang lama
2. Ratchet mengimplementasikan subprotokol WAMP, sehingga Anda dapat menerapkan pola komunikasi RPC dan Publikasikan & Berlangganan melalui soket web, tetapi untuk WAMP Anda memerlukan pustaka klien yang tercantum di sini
Kontra
1. Ratchet tidak mendukung SSL untuk server. Masalah ini dapat diatasi dengan proxy permintaan websocket ke Nginx, HAProxy atau stunnel pada mesin yang sama
2. Satu kesalahan akan menghentikan server websocket. Ini berarti bahwa kita harus menangani semua kesalahan yang mungkin terjadi pada aplikasi websocket dan tentu saja menutupinya dengan uji fungsional
3. Sulit untuk menskalakan secara horizontal. Anda perlu mengimplementasikan solusi Anda sendiri untuk penskalaan untuk berbagi koneksi antar mesin yang berbeda. HAProxy dapat membantu dalam hal ini
4. Jika Anda berinteraksi dengan database di dalam kelas WebSocketApplication, Anda selalu perlu memeriksa ketersediaannya dan menyambungkannya kembali jika koneksi terputus. Misalnya server Mysql memutuskan koneksi setelah beberapa waktu tidak aktif (secara default 8 jam). Ini berlaku untuk semua layanan atau lapisan aplikasi. Inilah yang kami lakukan ketika Doctrine ORM tidak dapat terhubung ke database. Jika tidak ada aktivitas terkait basis data dalam koneksi soket untuk waktu yang lama, kami mengalami kesalahan "server MySQL telah hilang". Memecahkan ini dengan try… catch block
$result = $repo->findOneBy($findOneByParams);
} catch (\Doctrine\DBAL\DBALException $ex) {
$this->reconnectToDatabase();
$result = $repo->findOneBy($findOneByParams);
}
Tautan yang bermanfaat
http. // soket. me/ — Pustaka Ratchet PHP untuk membuat aplikasi WebSocket
http. //reactphp.ini. org/ — Event-driven, non-blocking I/O dengan PHP
http. // www. leggetter. bersama. uk/ — halaman Phil Leggeter. Penginjil & Konsultan Web Real-Time
http. // www. leggetter. bersama. uk/real-time-web-technologies-guide/ — Panduan teknologi waktu nyata
http. //wamp-proto. org/ — Protokol Perpesanan Aplikasi Web
https. // www. Youtube. com/watch?v=04jVCKLXttk — Chris Boden berbicara tentang Ratchet di SKI PHP Conference
Alih-alih P. S
Solusi menarik lainnya yang sedang kami selidiki saat ini adalah server proxy bernama Pushpin yang merupakan proxy terbalik untuk Web waktu nyata. Ini adalah proyek sumber terbuka yang dikembangkan oleh Fanout. io. Ini menyediakan polling panjang, streaming HTTP, dan koneksi Websocket untuk klien dan memproksikan koneksi ini ke aplikasi backend Anda. Akibatnya — backend seharusnya tidak menangani koneksi yang berumur panjang sama sekali. Sebaliknya itu harus menerima dan mengirim permintaan HTTP sederhana, yang jelas merupakan pekerjaan untuk PHP dan Symfony dan untuk backend lainnya juga
Dengan demikian, integrasi Pushpin adalah pekerjaan kami yang sedang berjalan. Kami telah memutuskan untuk mengembangkan bundel Symfony2 (https. //github. com/smart-gamma/pushpin-bundle) untuk mengintegrasikannya dengan pustaka php-gripcontrol ke dalam aplikasi kita. Saat ini bundel ini sedang dalam proses pengembangan, jadi periksa pembaruan kami
Artikel tersebut dibuat berdasarkan pidato “Aplikasi Web Real-Time. Penggunaan Websocket dalam PHP” dari pengembang Senior Symfony2 kami — Stanislav Zozulya, selama konferensi pembangunan tim internal perusahaan kami 28. 11. 2015, Uzhorod, Ukraina