Async, streaming TCP/IP teks biasa dan server soket TLS aman serta koneksi klien untuk ReactPHP.
Versi pengembangan: Cabang ini berisi kode untuk rilis v3 mendatang. Untuk kode rilis stabil v1 saat ini, lihat cabang
1.x
Rilis v3 mendatang akan menjadi masa depan untuk paket ini. Namun, kami akan tetap aktif mendukung v1 bagi mereka yang belum menggunakan versi terbaru. Lihat juga petunjuk pemasangan untuk lebih jelasnya.
Pustaka soket menyediakan antarmuka yang dapat digunakan kembali untuk server dan klien lapisan soket berdasarkan komponen EventLoop
dan Stream
. Komponen servernya memungkinkan Anda membangun server jaringan yang menerima koneksi masuk dari klien jaringan (seperti server HTTP). Komponen kliennya memungkinkan Anda membangun klien jaringan yang membuat koneksi keluar ke server jaringan (seperti klien HTTP atau database). Pustaka ini menyediakan sarana streaming asinkron untuk semua ini, sehingga Anda dapat menangani beberapa koneksi bersamaan tanpa pemblokiran.
Daftar isi
Berikut adalah server yang menutup koneksi jika Anda mengirimkan sesuatu:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " Hello " . $ connection -> getRemoteAddress () . " ! n" );
$ connection -> write ( " Welcome to this amazing server! n" );
$ connection -> write ( " Here's a tip: don't say anything. n" );
$ connection -> on ( ' data ' , function ( $ data ) use ( $ connection ) {
$ connection -> close ();
});
});
Lihat juga contohnya.
Inilah klien yang mengeluarkan keluaran dari server tersebut dan kemudian mencoba mengirimkannya sebuah string:
$ connector = new React Socket Connector ();
$ connector -> connect ( ' 127.0.0.1:8080 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> pipe ( new React Stream WritableResourceStream ( STDOUT ));
$ connection -> write ( " Hello World! n" );
}, function ( Exception $ e ) {
echo ' Error: ' . $ e -> getMessage () . PHP_EOL ;
});
ConnectionInterface
digunakan untuk mewakili koneksi masuk dan keluar, seperti koneksi TCP/IP normal.
Koneksi masuk atau keluar adalah aliran dupleks (dapat dibaca dan ditulis) yang mengimplementasikan DuplexStreamInterface
React. Ini berisi properti tambahan untuk alamat lokal dan jarak jauh (IP klien) tempat koneksi ini dibuat ke/dari.
Umumnya, instance yang mengimplementasikan ConnectionInterface
ini dikeluarkan oleh semua kelas yang mengimplementasikan ServerInterface
dan digunakan oleh semua kelas yang mengimplementasikan ConnectorInterface
.
Karena ConnectionInterface
mengimplementasikan DuplexStreamInterface
yang mendasarinya, Anda dapat menggunakan peristiwa dan metode apa pun seperti biasa:
$ connection -> on ( ' data ' , function ( $ chunk ) {
echo $ chunk ;
});
$ connection -> on ( ' end ' , function () {
echo ' ended ' ;
});
$ connection -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage ();
});
$ connection -> on ( ' close ' , function () {
echo ' closed ' ;
});
$ connection -> write ( $ data );
$ connection -> end ( $ data = null );
$ connection -> close ();
// …
Untuk detail selengkapnya, lihat DuplexStreamInterface
.
Metode getRemoteAddress(): ?string
mengembalikan alamat jarak jauh lengkap (URI) tempat koneksi ini dibuat.
$ address = $ connection -> getRemoteAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Jika alamat jarak jauh tidak dapat ditentukan atau tidak diketahui saat ini (seperti setelah koneksi ditutup), maka MUNGKIN akan mengembalikan nilai NULL
.
Jika tidak, alamat lengkap (URI) akan dikembalikan sebagai nilai string, seperti tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
atau unix:///path/to/example.sock
. Perhatikan bahwa masing-masing komponen URI bersifat spesifik aplikasi dan bergantung pada protokol transport yang mendasarinya.
Jika ini adalah koneksi berbasis TCP/IP dan Anda hanya menginginkan IP jarak jauh, Anda dapat menggunakan sesuatu seperti ini:
$ address = $ connection -> getRemoteAddress ();
$ ip = trim ( parse_url ( $ address , PHP_URL_HOST ), ' [] ' );
echo ' Connection with ' . $ ip . PHP_EOL ;
Metode getLocalAddress(): ?string
mengembalikan alamat lokal lengkap (URI) tempat koneksi ini dibuat.
$ address = $ connection -> getLocalAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Jika alamat lokal tidak dapat ditentukan atau tidak diketahui saat ini (seperti setelah koneksi ditutup), maka MUNGKIN akan mengembalikan nilai NULL
.
Jika tidak, alamat lengkap (URI) akan dikembalikan sebagai nilai string, seperti tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
atau unix:///path/to/example.sock
. Perhatikan bahwa masing-masing komponen URI bersifat spesifik aplikasi dan bergantung pada protokol transport yang mendasarinya.
Metode ini melengkapi metode getRemoteAddress()
sehingga tidak perlu bingung.
Jika instance TcpServer
Anda mendengarkan pada beberapa antarmuka (misalnya menggunakan alamat 0.0.0.0
), Anda dapat menggunakan metode ini untuk mengetahui antarmuka mana yang benar-benar menerima koneksi ini (seperti antarmuka publik atau lokal).
Jika sistem Anda memiliki beberapa antarmuka (misalnya antarmuka WAN dan LAN), Anda dapat menggunakan metode ini untuk mengetahui antarmuka mana yang sebenarnya digunakan untuk koneksi ini.
ServerInterface
bertanggung jawab untuk menyediakan antarmuka untuk menerima koneksi streaming masuk, seperti koneksi TCP/IP normal.
Sebagian besar komponen tingkat tinggi (seperti server HTTP) menerima instance yang mengimplementasikan antarmuka ini untuk menerima koneksi streaming masuk. Hal ini biasanya dilakukan melalui injeksi ketergantungan, jadi cukup mudah untuk menukar implementasi ini dengan implementasi lain dari antarmuka ini. Ini berarti Anda HARUS mengetikkan petunjuk terhadap antarmuka ini alih-alih implementasi konkret dari antarmuka ini.
Selain mendefinisikan beberapa metode, antarmuka ini juga mengimplementasikan EventEmitterInterface
yang memungkinkan Anda bereaksi terhadap peristiwa tertentu.
Peristiwa connection
akan dikeluarkan setiap kali koneksi baru dibuat, yaitu klien baru terhubung ke soket server ini:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' new connection ' . PHP_EOL ;
});
Lihat juga ConnectionInterface
untuk rincian lebih lanjut tentang penanganan koneksi masuk.
Peristiwa error
akan dikeluarkan setiap kali ada kesalahan saat menerima koneksi baru dari klien.
$ socket -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage () . PHP_EOL ;
});
Perhatikan bahwa ini bukan kejadian kesalahan yang fatal, yaitu server tetap mendengarkan koneksi baru bahkan setelah kejadian ini.
Metode getAddress(): ?string
dapat digunakan untuk mengembalikan alamat lengkap (URI) yang sedang didengarkan server ini.
$ address = $ socket -> getAddress ();
echo ' Server listening on ' . $ address . PHP_EOL ;
Jika alamat tidak dapat ditentukan atau tidak diketahui saat ini (seperti setelah soket ditutup), maka MUNGKIN akan mengembalikan nilai NULL
.
Jika tidak, alamat lengkap (URI) akan dikembalikan sebagai nilai string, seperti tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
unix://example.sock
atau unix:///path/to/example.sock
. Perhatikan bahwa masing-masing komponen URI bersifat spesifik aplikasi dan bergantung pada protokol transport yang mendasarinya.
Jika ini adalah server berbasis TCP/IP dan Anda hanya menginginkan port lokal, Anda dapat menggunakan sesuatu seperti ini:
$ address = $ socket -> getAddress ();
$ port = parse_url ( $ address , PHP_URL_PORT );
echo ' Server listening on port ' . $ port . PHP_EOL ;
Metode pause(): void
dapat digunakan untuk menjeda penerimaan koneksi masuk baru.
Menghapus sumber daya soket dari EventLoop dan dengan demikian berhenti menerima koneksi baru. Perhatikan bahwa soket pendengaran tetap aktif dan tidak tertutup.
Artinya, koneksi masuk baru akan tetap tertunda di backlog sistem operasi hingga backlog yang dapat dikonfigurasi terisi. Setelah backlog terisi, sistem operasi dapat menolak koneksi masuk lebih lanjut hingga backlog terkuras lagi dengan melanjutkan menerima koneksi baru.
Setelah server dijeda, tidak ada peristiwa connection
lebih lanjut yang HARUS dikeluarkan.
$ socket -> pause ();
$ socket -> on ( ' connection ' , assertShouldNeverCalled ());
Metode ini hanya bersifat saran, meskipun umumnya tidak disarankan, server MUNGKIN terus memancarkan peristiwa connection
.
Kecuali dinyatakan sebaliknya, server yang berhasil dibuka TIDAK BOLEH dimulai dalam keadaan dijeda.
Anda dapat terus memproses kejadian dengan memanggil resume()
lagi.
Perhatikan bahwa kedua metode dapat dipanggil berapa kali pun, khususnya memanggil pause()
lebih dari sekali TIDAK BOLEH memberikan efek apa pun. Demikian pula, memanggil ini setelah close()
adalah NO-OP.
Metode resume(): void
dapat digunakan untuk melanjutkan penerimaan koneksi masuk baru.
Pasang kembali sumber daya soket ke EventLoop setelah pause()
sebelumnya.
$ socket -> pause ();
Loop:: addTimer ( 1.0 , function () use ( $ socket ) {
$ socket -> resume ();
});
Perhatikan bahwa kedua metode dapat dipanggil berapa kali pun, khususnya pemanggilan resume()
tanpa pause()
TIDAK BOLEH memberikan efek apa pun. Demikian pula, memanggil ini setelah close()
adalah NO-OP.
Metode close(): void
dapat digunakan untuk mematikan soket pendengaran ini.
Ini akan berhenti mendengarkan koneksi masuk baru pada soket ini.
echo ' Shutting down server socket ' . PHP_EOL ;
$ socket -> close ();
Memanggil metode ini lebih dari sekali pada contoh yang sama adalah NO-OP.
Kelas SocketServer
adalah kelas utama dalam paket ini yang mengimplementasikan ServerInterface
dan memungkinkan Anda menerima koneksi streaming masuk, seperti TCP/IP teks biasa atau aliran koneksi TLS aman.
Untuk menerima koneksi TCP/IP teks biasa, Anda cukup meneruskan kombinasi host dan port seperti ini:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
Mendengarkan alamat localhost 127.0.0.1
berarti tidak dapat dijangkau dari luar sistem ini. Untuk mengubah host tempat soket mendengarkan, Anda dapat memberikan alamat IP antarmuka atau menggunakan alamat khusus 0.0.0.0
untuk mendengarkan semua antarmuka:
$ socket = new React Socket SocketServer ( ' 0.0.0.0:8080 ' );
Jika Anda ingin mendengarkan pada alamat IPv6, Anda HARUS mengapit host dalam tanda kurung siku:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' );
Untuk menggunakan penetapan port acak, Anda dapat menggunakan port 0
:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:0 ' );
$ address = $ socket -> getAddress ();
Untuk mendengarkan jalur soket domain Unix (UDS), Anda HARUS mengawali URI dengan skema unix://
:
$ socket = new React Socket SocketServer ( ' unix:///tmp/server.sock ' );
Untuk mendengarkan nomor deskriptor file (FD) yang ada, Anda HARUS mengawali URI dengan php://fd/
seperti ini:
$ socket = new React Socket SocketServer ( ' php://fd/3 ' );
Jika URI yang diberikan tidak valid, tidak berisi port, skema lain, atau berisi nama host, maka akan muncul InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ socket = new React Socket SocketServer ( ' 127.0.0.1 ' );
Jika URI yang diberikan tampaknya valid, namun gagal mendengarkannya (seperti jika port sudah digunakan atau port di bawah 1024 mungkin memerlukan akses root, dll.), maka akan muncul RuntimeException
:
$ first = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
// throws RuntimeException because port is already in use
$ second = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
Perhatikan bahwa kondisi kesalahan ini mungkin berbeda-beda tergantung pada sistem dan/atau konfigurasi Anda. Lihat pesan dan kode pengecualian untuk detail selengkapnya tentang kondisi kesalahan sebenarnya.
Secara opsional, Anda dapat menentukan opsi konteks soket TCP untuk sumber daya soket aliran yang mendasarinya seperti ini:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' , [
' tcp ' => [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]
]);
Perhatikan bahwa opsi konteks soket yang tersedia, defaultnya, dan efek perubahannya mungkin berbeda-beda tergantung pada sistem dan/atau versi PHP Anda. Meneruskan opsi konteks yang tidak diketahui tidak berpengaruh. Opsi konteks
backlog
defaultnya adalah511
kecuali diberikan secara eksplisit.
Anda dapat memulai server TLS yang aman (sebelumnya dikenal sebagai SSL) hanya dengan menambahkan skema tls://
URI. Secara internal, ia akan menunggu koneksi TCP/IP teks biasa dan kemudian melakukan jabat tangan TLS untuk setiap koneksi. Oleh karena itu, diperlukan opsi konteks TLS yang valid, yang dalam bentuk paling dasar mungkin terlihat seperti ini jika Anda menggunakan file sertifikat yang dikodekan PEM:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8080 ' , [
' tls ' => [
' local_cert ' => ' server.pem '
]
]);
Perhatikan bahwa file sertifikat tidak akan dimuat saat instantiasi tetapi saat koneksi masuk menginisialisasi konteks TLS-nya. Artinya, jalur atau konten file sertifikat yang tidak valid hanya akan menyebabkan kejadian
error
di kemudian hari.
Jika kunci pribadi Anda dienkripsi dengan frasa sandi, Anda harus menentukannya seperti ini:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]
]);
Secara default, server ini mendukung TLSv1.0+ dan mengecualikan dukungan untuk SSLv2/SSLv3 lama. Anda juga dapat secara eksplisit memilih versi TLS yang ingin Anda negosiasikan dengan pihak jarak jauh:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]
]);
Perhatikan bahwa opsi konteks TLS yang tersedia, defaultnya, dan efek perubahannya mungkin berbeda-beda bergantung pada sistem dan/atau versi PHP Anda. Array konteks luar memungkinkan Anda juga menggunakan opsi konteks
tcp
(dan mungkin lebih banyak lagi) secara bersamaan. Meneruskan opsi konteks yang tidak diketahui tidak berpengaruh. Jika Anda tidak menggunakan skematls://
, meneruskan opsi kontekstls
tidak akan berpengaruh.
Setiap kali klien terhubung, ia akan mengeluarkan peristiwa connection
dengan instance koneksi yang mengimplementasikan ConnectionInterface
:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Lihat juga ServerInterface
untuk lebih jelasnya.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance loop peristiwa yang akan digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Perhatikan bahwa kelas
SocketServer
adalah implementasi nyata untuk soket TCP/IP. Jika Anda ingin mengetikkan implementasi protokol tingkat yang lebih tinggi, Anda HARUS menggunakanServerInterface
generik sebagai gantinya.
Kelas TcpServer
mengimplementasikan ServerInterface
dan bertanggung jawab untuk menerima koneksi TCP/IP teks biasa.
$ server = new React Socket TcpServer ( 8080 );
Seperti di atas, parameter $uri
hanya dapat terdiri dari satu port, dalam hal ini server akan mendengarkan secara default pada alamat localhost 127.0.0.1
, yang berarti tidak akan dapat dijangkau dari luar sistem ini.
Untuk menggunakan penetapan port acak, Anda dapat menggunakan port 0
:
$ server = new React Socket TcpServer ( 0 );
$ address = $ server -> getAddress ();
Untuk mengubah host tempat soket mendengarkan, Anda dapat memberikan alamat IP melalui parameter pertama yang diberikan ke konstruktor, secara opsional didahului dengan skema tcp://
:
$ server = new React Socket TcpServer ( ' 192.168.0.1:8080 ' );
Jika Anda ingin mendengarkan pada alamat IPv6, Anda HARUS mengapit host dalam tanda kurung siku:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' );
Jika URI yang diberikan tidak valid, tidak berisi port, skema lain, atau berisi nama host, maka akan muncul InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ server = new React Socket TcpServer ( ' 127.0.0.1 ' );
Jika URI yang diberikan tampaknya valid, namun gagal mendengarkannya (seperti jika port sudah digunakan atau port di bawah 1024 mungkin memerlukan akses root, dll.), maka akan muncul RuntimeException
:
$ first = new React Socket TcpServer ( 8080 );
// throws RuntimeException because port is already in use
$ second = new React Socket TcpServer ( 8080 );
Perhatikan bahwa kondisi kesalahan ini mungkin berbeda-beda tergantung pada sistem dan/atau konfigurasi Anda. Lihat pesan dan kode pengecualian untuk detail selengkapnya tentang kondisi kesalahan sebenarnya.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance event loop yang akan digunakan pada objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Secara opsional, Anda dapat menentukan opsi konteks soket untuk sumber daya soket aliran yang mendasarinya seperti ini:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' , null , [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]);
Perhatikan bahwa opsi konteks soket yang tersedia, defaultnya, dan efek perubahannya mungkin berbeda-beda tergantung pada sistem dan/atau versi PHP Anda. Meneruskan opsi konteks yang tidak diketahui tidak berpengaruh. Opsi konteks
backlog
defaultnya adalah511
kecuali diberikan secara eksplisit.
Setiap kali klien terhubung, ia akan mengeluarkan peristiwa connection
dengan instance koneksi yang mengimplementasikan ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Lihat juga ServerInterface
untuk lebih jelasnya.
Kelas SecureServer
mengimplementasikan ServerInterface
dan bertanggung jawab untuk menyediakan server TLS (sebelumnya dikenal sebagai SSL) yang aman.
Ia melakukannya dengan menggabungkan instance TcpServer
yang menunggu koneksi TCP/IP teks biasa dan kemudian melakukan jabat tangan TLS untuk setiap koneksi. Oleh karena itu, diperlukan opsi konteks TLS yang valid, yang dalam bentuk paling dasar mungkin terlihat seperti ini jika Anda menggunakan file sertifikat yang dikodekan PEM:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem '
]);
Perhatikan bahwa file sertifikat tidak akan dimuat saat instantiasi tetapi saat koneksi masuk menginisialisasi konteks TLS-nya. Artinya, jalur atau konten file sertifikat yang tidak valid hanya akan menyebabkan kejadian
error
di kemudian hari.
Jika kunci pribadi Anda dienkripsi dengan frasa sandi, Anda harus menentukannya seperti ini:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]);
Secara default, server ini mendukung TLSv1.0+ dan mengecualikan dukungan untuk SSLv2/SSLv3 lama. Anda juga dapat secara eksplisit memilih versi TLS yang ingin Anda negosiasikan dengan pihak jarak jauh:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]);
Perhatikan bahwa opsi konteks TLS yang tersedia, defaultnya, dan efek perubahannya mungkin berbeda-beda bergantung pada sistem dan/atau versi PHP Anda. Melewati opsi konteks yang tidak diketahui tidak berpengaruh.
Setiap kali klien menyelesaikan jabat tangan TLS, klien akan mengeluarkan peristiwa connection
dengan instance koneksi yang mengimplementasikan ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Secure connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Setiap kali klien gagal melakukan jabat tangan TLS yang berhasil, klien akan mengeluarkan peristiwa error
dan kemudian menutup koneksi TCP/IP yang mendasarinya:
$ server -> on ( ' error ' , function ( Exception $ e ) {
echo ' Error ' . $ e -> getMessage () . PHP_EOL ;
});
Lihat juga ServerInterface
untuk lebih jelasnya.
Perhatikan bahwa kelas SecureServer
adalah implementasi nyata untuk soket TLS. Jika Anda ingin mengetikkan implementasi protokol tingkat yang lebih tinggi, Anda HARUS menggunakan ServerInterface
generik sebagai gantinya.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance loop peristiwa yang akan digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Penggunaan tingkat lanjut: Meskipun mengizinkan
ServerInterface
sebagai parameter pertama, Anda HARUS meneruskan instanceTcpServer
sebagai parameter pertama, kecuali Anda tahu apa yang Anda lakukan. Secara internal,SecureServer
harus mengatur opsi konteks TLS yang diperlukan pada sumber daya aliran yang mendasarinya. Sumber daya ini tidak diekspos melalui antarmuka mana pun yang ditentukan dalam paket ini, tetapi hanya melalui kelasConnection
internal. KelasTcpServer
dijamin memancarkan koneksi yang mengimplementasikanConnectionInterface
dan menggunakan kelasConnection
internal untuk mengekspos sumber daya yang mendasarinya. Jika Anda menggunakanServerInterface
khusus dan peristiwaconnection
tidak memenuhi persyaratan ini,SecureServer
akan mengeluarkan peristiwaerror
dan kemudian menutup koneksi yang mendasarinya.
Kelas UnixServer
mengimplementasikan ServerInterface
dan bertanggung jawab untuk menerima koneksi pada soket domain Unix (UDS).
$ server = new React Socket UnixServer ( ' /tmp/server.sock ' );
Seperti di atas, parameter $uri
hanya dapat terdiri dari jalur soket atau jalur soket yang diawali dengan skema unix://
.
Jika URI yang diberikan tampaknya valid, namun gagal mendengarkannya (seperti jika soket sudah digunakan atau file tidak dapat diakses, dll.), maka akan muncul RuntimeException
:
$ first = new React Socket UnixServer ( ' /tmp/same.sock ' );
// throws RuntimeException because socket is already in use
$ second = new React Socket UnixServer ( ' /tmp/same.sock ' );
Perhatikan bahwa kondisi kesalahan ini mungkin berbeda-beda tergantung pada sistem dan/atau konfigurasi Anda. Secara khusus, Zend PHP hanya melaporkan "Kesalahan tidak diketahui" ketika jalur UDS sudah ada dan tidak dapat diikat. Anda mungkin ingin memeriksa
is_file()
pada jalur UDS yang diberikan untuk melaporkan pesan kesalahan yang lebih ramah pengguna dalam kasus ini. Lihat pesan dan kode pengecualian untuk detail selengkapnya tentang kondisi kesalahan sebenarnya.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance loop peristiwa yang akan digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Setiap kali klien terhubung, ia akan mengeluarkan peristiwa connection
dengan instance koneksi yang mengimplementasikan ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' New connection ' . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Lihat juga ServerInterface
untuk lebih jelasnya.
Dekorator LimitingServer
membungkus ServerInterface
tertentu dan bertanggung jawab untuk membatasi dan melacak koneksi terbuka ke instance server ini.
Setiap kali server yang mendasarinya mengeluarkan peristiwa connection
, ia akan memeriksa batasnya dan kemudian melakukan pemeriksaan lainnya
connection
error
.Setiap kali koneksi ditutup, koneksi ini akan dihapus dari daftar koneksi terbuka.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Lihat juga contoh kedua untuk lebih jelasnya.
Anda harus melewati jumlah maksimum koneksi terbuka untuk memastikan server akan secara otomatis menolak (menutup) koneksi setelah batas ini terlampaui. Dalam hal ini, ia akan mengeluarkan peristiwa error
untuk menginformasikan hal ini dan tidak ada peristiwa connection
yang akan dikeluarkan.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Anda MUNGKIN melewati batas null
untuk tidak membatasi jumlah koneksi terbuka dan terus menerima koneksi baru hingga Anda kehabisan sumber daya sistem operasi (seperti pegangan file terbuka). Ini mungkin berguna jika Anda tidak ingin menerapkan batasan namun tetap ingin menggunakan metode getConnections()
.
Anda juga dapat mengonfigurasi server untuk menjeda penerimaan koneksi baru setelah batas koneksi tercapai. Dalam hal ini, ini akan menghentikan sementara server yang mendasarinya dan tidak lagi memproses koneksi baru sama sekali, sehingga juga tidak lagi menutup koneksi yang berlebihan. Sistem operasi yang mendasarinya bertanggung jawab untuk menyimpan simpanan koneksi yang tertunda hingga batasnya tercapai, dan pada saat itulah sistem akan mulai menolak koneksi selanjutnya. Setelah server berada di bawah batas koneksi, server akan terus menggunakan koneksi dari backlog dan akan memproses data yang belum terselesaikan pada setiap koneksi. Mode ini mungkin berguna untuk beberapa protokol yang dirancang untuk menunggu pesan respons (seperti HTTP), namun mungkin kurang berguna untuk protokol lain yang memerlukan respons segera (seperti pesan "selamat datang" dalam obrolan interaktif).
$ server = new React Socket LimitingServer ( $ server , 100 , true );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Metode getConnections(): ConnectionInterface[]
dapat digunakan untuk mengembalikan array dengan semua koneksi yang sedang aktif.
foreach ( $ server -> getConnection () as $ connection ) {
$ connection -> write ( ' Hi! ' );
}
ConnectorInterface
bertanggung jawab untuk menyediakan antarmuka untuk membuat koneksi streaming, seperti koneksi TCP/IP normal.
Ini adalah antarmuka utama yang didefinisikan dalam paket ini dan digunakan di seluruh ekosistem React yang luas.
Sebagian besar komponen tingkat tinggi (seperti HTTP, database, atau klien layanan jaringan lainnya) menerima instance yang mengimplementasikan antarmuka ini untuk membuat koneksi TCP/IP ke layanan jaringan yang mendasarinya. Hal ini biasanya dilakukan melalui injeksi ketergantungan, jadi cukup mudah untuk menukar implementasi ini dengan implementasi lain dari antarmuka ini.
Antarmuka hanya menawarkan satu metode:
Metode connect(string $uri): PromiseInterface<ConnectionInterface>
dapat digunakan untuk membuat koneksi streaming ke alamat jarak jauh yang diberikan.
Ini mengembalikan Janji yang dipenuhi dengan aliran yang mengimplementasikan ConnectionInterface
jika berhasil atau ditolak dengan Exception
jika koneksi tidak berhasil:
$ connector -> connect ( ' google.com:443 ' )-> then (
function ( React Socket ConnectionInterface $ connection ) {
// connection successfully established
},
function ( Exception $ error ) {
// failed to connect due to $error
}
);
Lihat juga ConnectionInterface
untuk lebih jelasnya.
Janji yang dikembalikan HARUS dilaksanakan sedemikian rupa sehingga dapat dibatalkan apabila masih tertunda. Membatalkan janji yang tertunda HARUS menolak nilainya dengan Exception
. Ini HARUS membersihkan semua sumber daya dan referensi yang mendasarinya sebagaimana berlaku:
$ promise = $ connector -> connect ( $ uri );
$ promise -> cancel ();
Kelas Connector
adalah kelas utama dalam paket ini yang mengimplementasikan ConnectorInterface
dan memungkinkan Anda membuat koneksi streaming.
Anda dapat menggunakan konektor ini untuk membuat segala jenis koneksi streaming, seperti TCP/IP teks biasa, TLS aman, atau aliran koneksi Unix lokal.
Itu mengikat ke loop acara utama dan dapat digunakan seperti ini:
$ connector = new React Socket Connector ();
$ connector -> connect ( $ uri )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
}, function ( Exception $ e ) {
echo ' Error: ' . $ e -> getMessage () . PHP_EOL ;
});
Untuk membuat koneksi TCP/IP plaintext, Anda cukup meneruskan kombinasi host dan port seperti ini:
$ connector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Jika Anda tidak menentukan skema URI di URI tujuan, skema tersebut akan menganggap
tcp://
sebagai default dan membuat koneksi TCP/IP teks biasa. Perhatikan bahwa koneksi TCP/IP memerlukan bagian host dan port di URI tujuan seperti di atas, semua komponen URI lainnya bersifat opsional.
Untuk membuat koneksi TLS yang aman, Anda dapat menggunakan skema tls://
URI seperti ini:
$ connector -> connect ( ' tls://www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Untuk membuat koneksi soket domain Unix lokal, Anda dapat menggunakan skema URI unix://
seperti ini:
$ connector -> connect ( ' unix:///tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Metode
getRemoteAddress()
akan mengembalikan jalur soket domain Unix (UDS) target seperti yang diberikan pada metodeconnect()
, termasuk skemaunix://
, misalnyaunix:///tmp/demo.sock
. MetodegetLocalAddress()
kemungkinan besar akan mengembalikan nilainull
karena nilai ini tidak berlaku untuk koneksi UDS di sini.
Di bawah tenda, Connector
diimplementasikan sebagai fasad tingkat yang lebih tinggi untuk konektor tingkat yang lebih rendah yang diterapkan dalam paket ini. Artinya, ia juga membagikan semua fitur dan detail implementasinya. Jika Anda ingin mengetikkan implementasi protokol tingkat yang lebih tinggi, Anda HARUS menggunakan ConnectorInterface
generik sebagai gantinya.
Pada v1.4.0
, kelas Connector
secara default menggunakan algoritma happy eyeballs untuk terhubung secara otomatis melalui IPv4 atau IPv6 ketika nama host diberikan. Ini secara otomatis mencoba untuk terhubung menggunakan IPv4 dan IPv6 secara bersamaan (lebih memilih IPv6), sehingga menghindari masalah yang biasa dihadapi oleh pengguna dengan koneksi atau pengaturan IPv6 yang tidak sempurna. Jika Anda ingin kembali ke perilaku lama yang hanya melakukan pencarian IPv4 dan hanya mencoba satu koneksi IPv4, Anda dapat mengatur Connector
seperti ini:
$ connector = new React Socket Connector ([
' happy_eyeballs ' => false
]);
Demikian pula, Anda juga dapat memengaruhi perilaku DNS default sebagai berikut. Kelas Connector
akan mencoba mendeteksi pengaturan DNS sistem Anda (dan menggunakan server DNS publik Google 8.8.8.8
sebagai cadangan jika tidak dapat menentukan pengaturan sistem Anda) untuk menyelesaikan semua nama host publik menjadi alamat IP yang mendasarinya secara default. Jika Anda secara eksplisit ingin menggunakan server DNS khusus (seperti relai DNS lokal atau server DNS seluruh perusahaan), Anda dapat mengatur Connector
seperti ini:
$ connector = new React Socket Connector ([
' dns ' => ' 127.0.1.1 '
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Jika Anda tidak ingin menggunakan penyelesai DNS sama sekali dan ingin terhubung ke alamat IP saja, Anda juga dapat mengatur Connector
Anda seperti ini:
$ connector = new React Socket Connector ([
' dns ' => false
]);
$ connector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Lanjutan: Jika Anda memerlukan instance DNS ReactDnsResolverResolverInterface
khusus, Anda juga dapat mengatur Connector
Anda seperti ini:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ resolver = $ dnsResolverFactory -> createCached ( ' 127.0.1.1 ' );
$ connector = new React Socket Connector ([
' dns ' => $ resolver
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Secara default, skema URI tcp://
dan tls://
akan menggunakan nilai batas waktu yang mengikuti pengaturan default_socket_timeout
ini (yang defaultnya adalah 60an). Jika Anda menginginkan nilai batas waktu khusus, Anda cukup meneruskannya seperti ini:
$ connector = new React Socket Connector ([
' timeout ' => 10.0
]);
Demikian pula, jika Anda tidak ingin menerapkan batas waktu sama sekali dan membiarkan sistem operasi menanganinya, Anda dapat meneruskan tanda boolean seperti ini:
$ connector = new React Socket Connector ([
' timeout ' => false
]);
Secara default, Connector
mendukung skema URI tcp://
, tls://
dan unix://
. Jika Anda ingin secara eksplisit melarang hal-hal ini, Anda cukup memberikan tanda boolean seperti ini:
// only allow secure TLS connections
$ connector = new React Socket Connector ([
' tcp ' => false ,
' tls ' => true ,
' unix ' => false ,
));
$ connector -> connect ( ' tls://google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
tcp://
dan tls://
juga menerima opsi konteks tambahan yang diteruskan ke konektor yang mendasarinya. Jika Anda ingin meneruskan opsi konteks tambahan secara eksplisit, Anda cukup meneruskan array opsi konteks seperti ini:
// allow insecure TLS connections
$ connector = new React Socket Connector ([
' tcp ' => [
' bindto ' => ' 192.168.0.1:0 '
],
' tls ' => [
' verify_peer ' => false ,
' verify_peer_name ' => false
],
]);
$ connector -> connect ( ' tls://localhost:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Secara default, konektor ini mendukung TLSv1.0+ dan mengecualikan dukungan untuk SSLv2/SSLv3 lama. Anda juga dapat secara eksplisit memilih versi TLS yang ingin Anda negosiasikan dengan pihak jarak jauh:
$ connector = new React Socket Connector ([
' tls ' => [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]
]);
Untuk detail lebih lanjut tentang opsi konteks, silakan lihat dokumentasi PHP tentang opsi konteks soket dan opsi konteks SSL.
Lanjutan: Secara default, Connector
mendukung skema URI tcp://
, tls://
dan unix://
. Untuk ini, ia menyiapkan kelas konektor yang diperlukan secara otomatis. Jika Anda ingin meneruskan konektor khusus secara eksplisit untuk semua ini, Anda cukup meneruskan instance yang mengimplementasikan ConnectorInterface
seperti ini:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ resolver = $ dnsResolverFactory -> createCached ( ' 127.0.1.1 ' );
$ tcp = new React Socket HappyEyeBallsConnector ( null , new React Socket TcpConnector (), $ resolver );
$ tls = new React Socket SecureConnector ( $ tcp );
$ unix = new React Socket UnixConnector ();
$ connector = new React Socket Connector ([
' tcp ' => $ tcp ,
' tls ' => $ tls ,
' unix ' => $ unix ,
' dns ' => false ,
' timeout ' => false ,
]);
$ connector -> connect ( ' google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Secara internal, konektor
tcp://
akan selalu dibungkus oleh penyelesai DNS, kecuali Anda menonaktifkan DNS seperti pada contoh di atas. Dalam hal ini, konektortcp://
menerima nama host sebenarnya, bukan hanya alamat IP yang ditentukan, dan dengan demikian bertanggung jawab untuk melakukan pencarian. Secara internal, konektortls://
yang dibuat secara otomatis akan selalu membungkus konektortcp://
yang mendasarinya untuk membuat koneksi TCP/IP teks biasa yang mendasarinya sebelum mengaktifkan mode TLS aman. Jika Anda ingin menggunakan konektortcp://
khusus yang mendasarinya hanya untuk koneksi TLS yang aman, Anda dapat secara eksplisit meneruskan konektortls://
seperti di atas. Secara internal, konektortcp://
dantls://
akan selalu dibungkus denganTimeoutConnector
, kecuali Anda menonaktifkan batas waktu seperti pada contoh di atas.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance loop peristiwa yang akan digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Kelas TcpConnector
mengimplementasikan ConnectorInterface
dan memungkinkan Anda membuat koneksi TCP/IP teks biasa ke kombinasi port IP apa pun:
$ tcpConnector = new React Socket TcpConnector ();
$ tcpConnector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Lihat juga contohnya.
Upaya koneksi yang tertunda dapat dibatalkan dengan membatalkan janji yang tertunda seperti:
$ promise = $ tcpConnector -> connect ( ' 127.0.0.1:80 ' );
$ promise -> cancel ();
Memanggil cancel()
pada janji yang tertunda akan menutup sumber daya soket yang mendasarinya, sehingga membatalkan koneksi TCP/IP yang tertunda, dan menolak janji yang dihasilkan.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance loop peristiwa yang akan digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Anda juga dapat meneruskan opsi konteks soket tambahan ke konstruktor seperti ini:
$ tcpConnector = new React Socket TcpConnector ( null , [
' bindto ' => ' 192.168.0.1:0 '
]);
Perhatikan bahwa kelas ini hanya memungkinkan Anda untuk terhubung ke kombinasi port IP. Jika URI yang diberikan tidak valid, tidak berisi alamat IP dan port yang valid, atau berisi skema lain, URI akan ditolak dengan InvalidArgumentException
:
Jika URI yang diberikan tampaknya valid, namun koneksi ke URI tersebut gagal (seperti jika host jarak jauh menolak koneksi, dll.), maka URI tersebut akan ditolak dengan RuntimeException
.
Jika Anda ingin terhubung ke kombinasi hostname-port, lihat juga bab berikut.
Penggunaan tingkat lanjut: Secara internal,
TcpConnector
mengalokasikan sumber daya konteks kosong untuk setiap sumber daya aliran. Jika URI tujuan berisi parameter kuerihostname
, nilainya akan digunakan untuk menyiapkan nama rekan TLS. Ini digunakan olehSecureConnector
danDnsConnector
untuk memverifikasi nama rekan dan juga dapat digunakan jika Anda menginginkan nama rekan TLS khusus.
Kelas HappyEyeBallsConnector
mengimplementasikan ConnectorInterface
dan memungkinkan Anda membuat koneksi TCP/IP teks biasa ke kombinasi nama host-port apa pun. Secara internal ia mengimplementasikan algoritma happy eyeballs dari RFC6555
dan RFC8305
untuk mendukung nama host IPv6 dan IPv4.
Ia melakukannya dengan mendekorasi instance TcpConnector
tertentu sehingga ia terlebih dahulu mencari nama domain yang diberikan melalui DNS (jika ada) dan kemudian membuat koneksi TCP/IP yang mendasarinya ke alamat IP target yang telah diselesaikan.
Pastikan untuk menyiapkan penyelesai DNS dan konektor TCP yang mendasarinya seperti ini:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ dns = $ dnsResolverFactory -> createCached ( ' 8.8.8.8 ' );
$ dnsConnector = new React Socket HappyEyeBallsConnector ( null , $ tcpConnector , $ dns );
$ dnsConnector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Lihat juga contohnya.
Upaya koneksi yang tertunda dapat dibatalkan dengan membatalkan janji yang tertunda seperti:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Memanggil cancel()
pada janji yang tertunda akan membatalkan pencarian DNS yang mendasarinya dan/atau koneksi TCP/IP yang mendasarinya dan menolak janji yang dihasilkan.
Kelas ini mengambil parameter opsional LoopInterface|null $loop
yang dapat digunakan untuk meneruskan instance loop peristiwa yang akan digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini TIDAK BOLEH diberikan kecuali Anda yakin ingin menggunakan instance loop peristiwa tertentu secara eksplisit.
Penggunaan tingkat lanjut: Secara internal,
HappyEyeBallsConnector
mengandalkanResolver
untuk mencari alamat IP untuk nama host yang diberikan. Kemudian akan mengganti nama host di URI tujuan dengan IP ini dan menambahkan parameter kuerihostname
dan meneruskan URI yang diperbarui ini ke konektor yang mendasarinya. Algoritme Happy Eye Balls menjelaskan pencarian alamat IPv6 dan IPv4 untuk nama host tertentu sehingga konektor ini mengirimkan dua pencarian DNS untuk data A dan AAAA. Ia kemudian menggunakan semua alamat IP (v6 dan v4) dan mencoba menyambung ke semuanya dengan interval 50 ms di antaranya. Mengubah antara alamat IPv6 dan IPv4. Ketika koneksi dibuat, semua pencarian DNS lainnya dan upaya koneksi dibatalkan.
Kelas DnsConnector
mengimplementasikan ConnectorInterface
dan memungkinkan Anda membuat koneksi TCP/IP teks biasa ke kombinasi nama host-port apa pun.
Ia melakukannya dengan mendekorasi instance TcpConnector
tertentu sehingga ia terlebih dahulu mencari nama domain yang diberikan melalui DNS (jika berlaku) dan kemudian membuat koneksi TCP/IP yang mendasarinya ke alamat IP target yang telah diselesaikan.
Pastikan untuk menyiapkan penyelesai DNS dan konektor TCP yang mendasarinya seperti ini:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ dns = $ dnsResolverFactory -> createCached ( ' 8.8.8.8 ' );
$ dnsConnector = new React Socket DnsConnector ( $ tcpConnector , $ dns );
$ dnsConnector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Lihat juga contohnya.
Upaya koneksi yang tertunda dapat dibatalkan dengan membatalkan janji yang tertunda seperti:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Memanggil cancel()
pada janji yang tertunda akan membatalkan pencarian DNS yang mendasarinya dan/atau koneksi TCP/IP yang mendasarinya dan menolak janji yang dihasilkan.
Penggunaan tingkat lanjut: Secara internal,
DnsConnector
mengandalkanReactDnsResolverResolverInterface
untuk mencari alamat IP untuk nama host yang diberikan. Kemudian akan mengganti nama host di URI tujuan dengan IP ini dan menambahkan parameter kuerihostname
dan meneruskan URI yang diperbarui ini ke konektor yang mendasarinya. Konektor yang mendasarinya bertanggung jawab untuk membuat koneksi ke alamat IP target, sementara parameter kueri ini dapat digunakan untuk memeriksa nama host asli dan digunakan olehTcpConnector
untuk menyiapkan nama rekan TLS. Jikahostname
diberikan secara eksplisit, parameter kueri ini tidak akan diubah, yang dapat berguna jika Anda menginginkan nama rekan TLS khusus.
Kelas SecureConnector
mengimplementasikan ConnectorInterface
dan memungkinkan Anda membuat koneksi TLS (sebelumnya dikenal sebagai SSL) yang aman ke kombinasi port-nama host apa pun.
Ia melakukannya dengan mendekorasi instance DnsConnector
tertentu sehingga ia terlebih dahulu membuat koneksi TCP/IP teks biasa dan kemudian mengaktifkan enkripsi TLS pada aliran ini.
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector );
$ secureConnector -> connect ( ' www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " GET / HTTP/1.0 rn Host: www.google.com rnrn" );
. . .
});
Lihat juga contohnya.
Upaya koneksi yang tertunda dapat dibatalkan dengan membatalkan janji yang tertunda seperti:
$ promise = $ secureConnector -> connect ( ' www.google.com:443 ' );
$ promise -> cancel ();
Panggilan cancel()
Pada janji yang tertunda akan membatalkan koneksi TCP/IP yang mendasarinya dan/atau negosiasi SSL/TLS dan menolak janji yang dihasilkan.
Kelas ini mengambil LoopInterface|null $loop
parameter yang dapat digunakan untuk lulus instance loop acara untuk digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini tidak boleh diberikan kecuali Anda yakin ingin menggunakan instance loop acara yang diberikan.
Anda secara opsional dapat melewati opsi konteks SSL tambahan ke konstruktor seperti ini:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' verify_peer ' => false ,
' verify_peer_name ' => false
]);
Secara default, konektor ini mendukung TLSV1.0+ dan tidak termasuk dukungan untuk Legacy SSLV2/SSLV3. Anda juga dapat secara eksplisit memilih versi TLS yang ingin Anda negosiasikan dengan sisi jarak jauh:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]);
Penggunaan Lanjutan: Secara internal,
SecureConnector
bergantung pada pengaturan opsi konteks yang diperlukan pada sumber daya aliran yang mendasarinya. Oleh karena itu harus digunakan denganTcpConnector
di suatu tempat di tumpukan konektor sehingga dapat mengalokasikan sumber daya konteks kosong untuk setiap sumber daya aliran dan memverifikasi nama rekan. Gagal melakukannya dapat mengakibatkan kesalahan nama peer name TLS atau beberapa kondisi ras yang sulit untuk dilacak, karena semua sumber daya aliran akan menggunakan sumber daya konteks default tunggal yang dibagikan.
Kelas TimeoutConnector
mengimplementasikan ConnectorInterface
dan memungkinkan Anda untuk menambahkan penanganan batas waktu ke instance konektor yang ada.
Ia melakukannya dengan mendekorasi instance ConnectorInterface
yang diberikan dan memulai timer yang secara otomatis akan menolak dan membatalkan upaya koneksi yang mendasarinya jika terlalu lama.
$ timeoutConnector = new React Socket TimeoutConnector ( $ connector , 3.0 );
$ timeoutConnector -> connect ( ' google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
// connection succeeded within 3.0 seconds
});
Lihat juga salah satu contohnya.
Kelas ini mengambil LoopInterface|null $loop
parameter yang dapat digunakan untuk lulus instance loop acara untuk digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini tidak boleh diberikan kecuali Anda yakin ingin menggunakan instance loop acara yang diberikan.
Upaya koneksi yang tertunda dapat dibatalkan dengan membatalkan janji yang tertunda seperti:
$ promise = $ timeoutConnector -> connect ( ' google.com:80 ' );
$ promise -> cancel ();
Memanggil cancel()
Pada janji yang tertunda akan membatalkan upaya koneksi yang mendasarinya, membatalkan timer dan menolak janji yang dihasilkan.
Kelas UnixConnector
mengimplementasikan ConnectorInterface
dan memungkinkan Anda untuk terhubung ke jalur domain unix (UDS) seperti ini:
$ connector = new React Socket UnixConnector ();
$ connector -> connect ( ' /tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " HELLO n" );
});
Menghubungkan ke soket domain UNIX adalah operasi atom, yaitu janjinya akan menyelesaikan (baik menyelesaikan atau menolak) segera. Dengan demikian, panggilan cancel()
pada janji yang dihasilkan tidak berpengaruh.
Metode
getRemoteAddress()
akan mengembalikan jalur soket domain unix target (UDS) seperti yang diberikan pada metodeconnect()
, yang dipersiapkan dengan skemaunix://
, misalnyaunix:///tmp/demo.sock
. MetodegetLocalAddress()
kemungkinan besar akan mengembalikan nilainull
karena nilai ini tidak berlaku untuk koneksi UDS di sini.
Kelas ini mengambil LoopInterface|null $loop
parameter yang dapat digunakan untuk lulus instance loop acara untuk digunakan untuk objek ini. Anda dapat menggunakan nilai null
di sini untuk menggunakan loop default. Nilai ini tidak boleh diberikan kecuali Anda yakin ingin menggunakan instance loop acara yang diberikan.
Kelas FixedUriConnector
mengimplementasikan ConnectorInterface
dan menghiasi konektor yang ada untuk selalu menggunakan URI yang telah dikonfigurasikan sebelumnya.
Ini dapat bermanfaat bagi konsumen yang tidak mendukung URI tertentu, seperti ketika Anda ingin secara eksplisit terhubung ke jalur Socket (UDS) UNIX Domain alih-alih menghubungkan ke alamat default yang diasumsikan oleh API tingkat yang lebih tinggi:
$ connector = new React Socket FixedUriConnector (
' unix:///var/run/docker.sock ' ,
new React Socket UnixConnector ()
);
// destination will be ignored, actually connects to Unix domain socket
$ promise = $ connector -> connect ( ' localhost:80 ' );
Cara yang disarankan untuk menginstal perpustakaan ini adalah melalui Komposer. Baru mengenal Komposer?
Setelah dirilis, proyek ini akan mengikuti SemVer. Saat ini, ini akan menginstal versi pengembangan terbaru:
composer require react/socket:^3@dev
Lihat juga CHANGELOG untuk detail tentang peningkatan versi.
Proyek ini bertujuan untuk berjalan pada platform apa pun sehingga tidak memerlukan ekstensi PHP apa pun dan mendukung berjalan pada PHP 7.1 hingga PHP 8+ saat ini. Sangat disarankan untuk menggunakan versi PHP terbaru yang didukung untuk proyek ini.
Legacy PHP <7.3.3 (dan PHP <7.2.15) menderita bug di mana feof () dapat memblokir dengan 100% penggunaan CPU pada catatan TLS terfragmentasi. Kami mencoba mengatasi hal ini dengan selalu mengonsumsi buffer menerima lengkap sekaligus untuk menghindari data basi dalam buffer TLS. Ini diketahui bekerja di sekitar penggunaan CPU yang tinggi untuk rekan-rekan yang berperan baik, tetapi ini dapat menyebabkan potongan data yang sangat besar untuk skenario throughput tinggi. Perilaku kereta masih dapat dipicu karena buffer I/O jaringan atau rekan jahat pada versi yang terpengaruh, peningkatan sangat dianjurkan.
Legacy PHP <7.1.4 menderita bug saat menulis potongan data besar melalui aliran TLS sekaligus. Kami mencoba mengatasi hal ini dengan membatasi ukuran potongan tulis menjadi 8192 byte hanya untuk versi PHP yang lebih lama. Ini hanya kerja-sekitar dan memiliki penalti kinerja yang terlihat pada versi yang terpengaruh.
Untuk menjalankan test suite, Anda harus mengkloning repo ini terlebih dahulu, lalu menginstal semua dependensi melalui Composer:
composer install
Untuk menjalankan rangkaian pengujian, buka root proyek dan jalankan:
vendor/bin/phpunit
Suite tes juga berisi sejumlah tes integrasi fungsional yang bergantung pada koneksi internet yang stabil. Jika Anda tidak ingin menjalankan ini, mereka dapat dilewati seperti ini:
vendor/bin/phpunit --exclude-group internet
MIT, lihat file LISENSI.