Aleph memaparkan data dari jaringan sebagai aliran Manifold, yang dapat dengan mudah diubah menjadi java.io.InputStream
, saluran core.async, urutan Clojure, atau banyak representasi byte lainnya. Ini memperlihatkan wrapper default sederhana untuk HTTP, TCP, dan UDP, namun memungkinkan akses ke kinerja penuh dan fleksibilitas pustaka Netty yang mendasarinya.
Leiningen:
[aleph " 0.8.2 " ]
deps.edn:
aleph/aleph { :mvn/version " 0.8.2 " }
; ; alternatively
io.github.clj-commons/aleph { :git/sha " ... " }
Aleph mengikuti spesifikasi Ring sepenuhnya, dan dapat menjadi pengganti untuk server yang mendukung Ring yang ada. Namun, hal ini juga memungkinkan fungsi handler mengembalikan Manifold yang ditangguhkan untuk mewakili respons akhir. Fitur ini mungkin tidak berfungsi dengan baik dengan middleware Ring sinkron yang mengubah respons, namun hal ini dapat dengan mudah diperbaiki dengan mengimplementasikan kembali middleware menggunakan operator let-flow Manifold. Helper aleph.http/wrap-ring-async-handler
dapat digunakan untuk mengonversi pengendali Ring 3-arity async menjadi yang sesuai dengan Aleph.
( require '[aleph.http :as http])
( defn handler [req]
{ :status 200
:headers { " content-type " " text/plain " }
:body " hello! " })
( http/start-server handler { :port 8080 }) ; HTTP/1-only
; ; To support HTTP/2, do the following:
; ; (def my-ssl-context ...)
( http/start-server handler { :port 443
:http-versions [ :http2 :http1 ]
:ssl-context my-ssl-context})
; ; See aleph.examples.http2 for more details
Badan respons juga dapat berupa aliran Manifold, di mana setiap pesan dari aliran dikirim sebagai satu kesatuan, memungkinkan kontrol yang tepat atas respons yang dialirkan untuk peristiwa yang dikirim server dan tujuan lainnya.
Untuk permintaan klien HTTP, Aleph memodelkan dirinya sendiri setelah clj-http, kecuali bahwa setiap permintaan segera mengembalikan Manifold yang ditangguhkan yang mewakili respons.
( require
'[aleph.http :as http]
'[manifold.deferred :as d]
'[clj-commons.byte-streams :as bs])
( -> @( http/get " https://google.com/ " )
:body
bs/to-string
prn)
( d/chain ( http/get " https://google.com " )
:body
bs/to-string
prn)
; ; To support HTTP/2, do the following:
( def conn-pool
( http/connection-pool { :connection-options { :http-versions [ :http2 :http1 ]}}))
@( http/get " https://google.com " { :pool conn-pool})
; ; See aleph.examples.http2 for more details
Aleph mencoba meniru API dan kemampuan clj-http sepenuhnya. Ini mendukung permintaan multipart/formulir data, penyimpanan cookie, server proxy, dan pemeriksaan permintaan dengan beberapa perbedaan penting:
konfigurasi proxy harus diatur untuk koneksi saat menyiapkan kumpulan koneksi, pengaturan proxy per permintaan tidak diperbolehkan
Fungsionalitas proksi HTTP diperluas dengan pengaturan terowongan, header HTTP opsional, dan kontrol batas waktu koneksi, lihat semua kunci konfigurasi
:proxy-ignore-hosts
tidak didukung
baik middleware cookie maupun penyimpanan cookie bawaan tidak mendukung parameter cookie yang sudah usang sejak RFC2965: komentar, URL komentar, buang, versi (lihat struktur cookie selengkapnya)
saat menggunakan :debug
, :save-request?
dan :debug-body?
pilihan, permintaan terkait akan disimpan di :aleph/netty-request
, :aleph/request
, :aleph/request-body
kunci peta respons
:response-interceptor
tidak didukung
Aleph memperkenalkan konfigurasi kumpulan koneksi :log-activity
untuk mengaktifkan pencatatan perubahan status koneksi serta hex dump permintaan/respons
Opsi :cache
dan :cache-config
tidak didukung seperti saat ini
Klien Aleph juga mendukung pemecah DNS yang sepenuhnya asinkron dan sangat dapat disesuaikan.
Untuk mempelajari lebih lanjut, baca kode contoh.
Pada versi 0.7.0, Aleph mendukung HTTP/2 di klien dan server.
Secara umum, dukungan HTTP/2 Aleph merupakan pengganti HTTP/1. Namun, untuk kompatibilitas mundur, Aleph secara default hanya menggunakan HTTP/1. Lihat contoh kode HTTP/2 untuk gambaran umum yang bagus tentang cara memulai HTTP/2.
Hal-hal yang perlu diperhatikan:
pipeline-transform
untuk mengubah pipeline Netty yang mendasarinya, Anda perlu memeriksa penggunaannya untuk HTTP/2. Di balik terpalnya, kode HTTP/2 yang baru menggunakan pengaturan pipeline multipleks Netty, dengan pipeline tingkat koneksi bersama yang mengumpankan frame spesifik aliran ke N pipeline yang dibuat untuk N aliran individual. (Pasangan permintaan/respons HTTP standar dipetakan ke satu aliran H2.) Pada permintaan HTTP apa pun yang memiliki header Upgrade
yang sesuai, Anda dapat memanggil (aleph.http/websocket-connection req)
, yang mengembalikan deferred yang menghasilkan aliran dupleks , yang menggunakan aliran tunggal untuk mewakili komunikasi dua arah. Pesan dari klien dapat diterima melalui take!
, dan dikirim ke klien melalui put!
. Oleh karena itu, penangan echo WebSocket hanya terdiri dari:
( require '[manifold.stream :as s])
( defn echo-handler [req]
( let [s @( http/websocket-connection req)]
( s/connect s s)))
Ini mengambil semua pesan dari klien, dan memasukkannya kembali ke soket duplex, mengembalikannya ke klien. Pesan teks WebSocket akan dikeluarkan sebagai string, dan pesan biner sebagai array byte.
Klien WebSocket dapat dibuat melalui (aleph.http/websocket-client url)
, yang mengembalikan penundaan yang menghasilkan aliran dupleks yang dapat mengirim dan menerima pesan dari server.
Untuk mempelajari lebih lanjut, baca kode contoh.
Server TCP mirip dengan server HTTP, hanya saja untuk setiap koneksi, pengendali mengambil dua argumen: aliran dupleks dan peta yang berisi informasi tentang klien. Aliran akan memancarkan array byte, yang dapat dipaksakan ke representasi byte lain menggunakan perpustakaan byte-streams. Aliran akan menerima pesan apa pun yang dapat dipaksa menjadi representasi biner.
Server echo TCP sangat mirip dengan contoh WebSocket di atas:
( require '[aleph.tcp :as tcp])
( defn echo-handler [s info]
( s/connect s s))
( tcp/start-server echo-handler { :port 10001 })
Klien TCP dapat dibuat melalui (aleph.tcp/client {:host "example.com", :port 10001})
, yang mengembalikan deferred yang menghasilkan aliran dupleks.
Untuk mempelajari lebih lanjut, baca kode contoh.
Soket UDP dapat dibuat menggunakan (aleph.udp/socket {:port 10001, :broadcast? false})
. Jika :port
ditentukan, maka akan menghasilkan soket dupleks yang dapat digunakan untuk mengirim dan menerima pesan, yang disusun sebagai peta dengan data berikut:
{ :host " example.com "
:port 10001
:message ...}
Dimana paket masuk akan memiliki :message
yaitu array byte, yang dapat dipaksa menggunakan byte-streams
, dan paket keluar dapat berupa data apa pun yang dapat dipaksa ke representasi biner. Jika :port
tidak ditentukan, soket hanya dapat digunakan untuk mengirim pesan.
Untuk mempelajari lebih lanjut, baca kode contoh.
Aleph menggunakan Leiningen untuk mengelola dependensi, menjalankan REPL dan pengujian, serta membuat kode.
Dukungan minimal tools.deps
tersedia dalam bentuk file deps.edn
yang dihasilkan dari project.clj
. Ini menyediakan cukup untuk dapat menggunakan Aleph sebagai ketergantungan git atau :local/root
. Saat melakukan perubahan pada project.clj
, jalankan deps/lein-to-deps
dan lakukan juga perubahan yang dihasilkan.
Hak Cipta © 2010-2024 Zachary Tellman
Didistribusikan di bawah Lisensi MIT.
Terima kasih banyak kepada YourKit karena mendukung Aleph. YourKit mendukung proyek sumber terbuka dengan alat inovatif dan cerdas untuk memantau dan membuat profil aplikasi Java dan .NET.
YourKit adalah pencipta YourKit Java Profiler, YourKit .NET Profiler, dan YourKit YouMonitor.