Harus cepat. Mengoptimalkan permintaan konten email IMAP

Halo semuanya! Dalam artikel sebelumnya, saya berbicara tentang bagaimana Anda dapat dengan cepat menyinkronkan isi kotak di cache lokal. Di sini saya ingin berbicara tentang fitur meminta isi surat dan cara terbaik untuk meminta konten, tidak takut dengan konsumsi lalu lintas tinggi.

gambar

Mari kita cepat mengingat apa yang kita pelajari di artikel terakhir:

  • IMAP adalah protokol stateful
  • Untuk melihat isi kotak masuk, Anda harus memilihnya terlebih dahulu dengan perintah SELECT
  • Untuk menyinkronkan kotak tempat kami berada, Anda dapat menggunakan perintah NOOP
  • Agar tidak mengurutkan pesan dari penyimpanan lokal untuk memperbarui kotak surat yang telah kami tinggalkan, Anda dapat menggunakan CONDSTORE dan QRESYNC, asalkan server Anda mendukung data ekstensi protokol

Cukup!


Biarkan saya mengingatkan Anda perintah untuk meminta isi surat:

1 FETCH number (BODY[])

Ini akan membuat permintaan untuk mendapatkan seluruh isi surat dan semua lampiran. Lihat saja berapa lama untuk mendapatkan pesan dalam 42 paragraf Lorem Ipsum dan dengan gambar 2 megabita.

Pertama, tanyakan ukuran pesan di server. Ini dilakukan oleh perintah:

1 FETCH 18871 (RFC822.SIZE)

RFC822.SIZE mengembalikan ukuran pesan dalam byte:

* 18871 FETCH (RFC822.SIZE 3937793)

Akibatnya, pesan kami memakan hampir 4 megabita.

Sekarang, bagaimanapun, kami akan menggunakan permintaan untuk isi penuh surat itu dan melihat pada saat itu:

1 OK Fetch completed (0.007 + 3.265 secs).

3,3 detik! Dan ini hanya satu pesan dengan lampiran, dan bayangkan mereka akan menjadi seluruh kotak. Maka akan diperlukan lebih dari satu menit untuk mengunduh setidaknya dua puluh satu yang pertama.

Anda harus mengakui bahwa bisnis klien yang pada tahun 2020 tidak dapat menyinkronkan surat lebih cepat daripada dalam satu menit adalah buruk. Tetapi apa yang harus dilakukan?

Beri aku gigitan sekali


Jika Anda membuat RFC3501 dalam klausa 6.5.4 , yang menjelaskan parameter yang mungkin untuk perintah FETCH, Anda akan melihat permintaan yang menarik:

BODY[<section>]<<partial>>

  • bagian - bagian mana dari surat untuk mendapatkan
  • parsial - ukuran bagian ini

Bagaimana sebagian dibangun? Dan itu sangat mudah. Pertama, byte dari mana Anda harus mulai membaca ditulis melalui titik, dan kemudian berapa byte secara umum harus dibaca:

BODY[<section>]<<0.1024>>

Di sini kami meminta bagian surat dari nol byte ke 1024.

Oke, apa bagian itu? Pertama, saya akan berbicara tentang parameter yang sangat berguna dalam permintaan FETCH sebagai BODYSTRUCTURE:

1 FETCH 18871 (BODYSTRUCTURE)

Parameter ini, seperti yang mungkin Anda mengerti dari tanda tangan, mengembalikan struktur surat dalam bentuk yang dijelaskan dalam MIME-IMB .

* 18871 FETCH (BODYSTRUCTURE ((("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 25604 337 NIL NIL NIL NIL)("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 29593 390 NIL NIL NIL NIL) "alternative" ("boundary" "--=_Part_763_774309787.1586268692") NIL NIL NIL)("image" "jpeg" ("name" "IMG_20200217_000236.jpg") NIL NIL "base64" 3880726 NIL ("attachment" ("filename" "IMG_20200217_000236.jpg")) NIL NIL) "mixed" ("boundary" "--=_Part_210_297656922.1586268692") NIL NIL NIL))


Lihat saja struktur ini, dan kepala Anda berputar? Jangan takut, sekarang kami akan mengetahuinya. Bandingkan kurung buka dan tutup.

(
BODYSTRUCTURE 
(
[1] (
[1.1] ("text" "plain" ("charset" "utf-8") NIL NIL "quoted-printable" 25604 337 NIL NIL NIL NIL)
[1.2] ("text" "html" ("charset" "utf-8") NIL NIL "quoted-printable" 29593 390 NIL NIL NIL NIL) "alternative" ("boundary" "--=_Part_763_774309787.1586268692") NIL NIL NIL
)
[2] ("image" "jpeg" ("name" "IMG_20200217_000236.jpg") NIL NIL "base64" 3880726 NIL ("attachment" ("filename" "IMG_20200217_000236.jpg")) NIL NIL) "mixed" ("boundary" "--=_Part_210_297656922.1586268692") NIL NIL NIL
)
)


Anda mungkin memperhatikan bahwa saya meletakkan angka di dekat beberapa tanda kurung. Ini bagian.
Bagaimana cara menghitungnya? Braket pertama harus dilewati, karena hanya berisi jawaban atas permintaan, maka setiap braket pembuka harus diberi nomor sesuai dengan aturan karena judul dalam dokumen diberi nomor:

  • Kami memberi nomor pada setiap braket pembuka dengan mempertimbangkan bagian sebelumnya
  • Jika bagian tersebut bersarang, maka bagian saat ini melalui titik ditambahkan ke nomor sebelumnya
  • Jika bagian tersebut tidak bersarang, tambah jumlahnya satu


Misalnya, dalam hal ini, di bagian pertama yang diakhiri dengan "alternatif" (yaitu, ini adalah bagian dari huruf multi-bagian / alternatif, di mana kita bebas memilih bagian mana yang akan ditampilkan untuk pengguna), ada dua bagian yang diberi nomor melalui titik. Saya bertemu dengan server di mana mungkin ada tiga tingkat bersarang (yaitu, [1.1.1], [1.1.2], dll).
Mari kita menganalisis bagian [1.1] melihat struktur semua hal ini dalam dokumen MIME-IMB . Dilihat oleh itu, header Jenis Konten adalah yang pertama. Itu termasuk:

  • Jenis MIME, ini dia teks / polos
  • Pengkodean (charset = utf8)


Berikut ini adalah dua parameter yang ditulis sebagai NIL. Terus terang, saya tidak mengerti apa itu, tetapi sejauh ini saya belum membutuhkannya, jadi saya akan melewatkannya. Saya minta maaf atas kesembronoan seperti ini.
Berikutnya adalah header Content-Transfer-Encoding, termasuk di dalamnya, yang menggambarkan mekanisme pengkodean, di sini dikutip-cetak. 
Dua angka berikut ini menjelaskan ukuran bagian dalam byte dan jumlah garis, jika memungkinkan. Dengan bantuan mereka, kita dapat menghitung berapa byte yang harus diambil untuk menampilkan sejumlah garis.
Baris berikut yang tidak ada di bagian ini:

  • Content-Id, yang digunakan dalam inline surat itu
  • Konten-Deskripsi, garis yang menjelaskan apa bagian ini


Untuk dua parameter lainnya, saya tidak dapat menemukan jawaban yang pasti apa itu, tetapi salah satu dari parameter ini mungkin mengandung bagian MD5, yang kadang-kadang bisa berguna.
Untuk bagian [2], semuanya sama, kecuali bahwa itu adalah gambar, lampiran dengan nama, dan pengkodean base64. Jika masih belum sepenuhnya jelas apa yang terjadi di sini, maka di situs ini ditata dengan sempurna bagaimana cara menghitung bagian.

Apa yang diberikannya? Dan fakta bahwa pada tahap menampilkan surat kita sudah dapat meminta hanya bagian atas konten dan tidak memuat lampiran sampai pengguna sendiri memasukkan pesan dan mengklik tombol "unduh". Semua informasi untuk menampilkan lampiran datang kepada kami di BODYSCTRUCTURE sehingga nama, format, dan ukuran dapat ditampilkan tanpa memuat lampiran itu sendiri. 

Mari kita lanjutkan berlatih. Kami akan meminta satu kilobyte konten pesan tanpa lampiran, hanya untuk mengetahui apa yang mereka kirimkan kepada kami.

1 fetch 18871 (body[1.1]<0.1024>)
* 18871 FETCH (BODY[1.1]<0> {1024}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus consecte=
tur enim in nisi venenatis, id varius tellus viverra. Praesent et enim te=
llus. Nunc vestibulum diam tortor, id posuere turpis tempor luctus. Vivam=
us molestie non nunc nec placerat. Cras finibus ut erat et tristique. Cur=
abitur vitae commodo risus. Etiam sed scelerisque erat. Quisque cursus bl=
andit finibus. Nullam ac lectus accumsan, molestie quam non, mollis urna.=
 Nulla at arcu in libero condimentum mollis ut non velit. Vestibulum sed =
risus et magna congue iaculis. Vestibulum nec interdum elit, ut commodo m=
auris. Nulla ipsum leo, vestibulum nec ligula non, elementum ullamcorper =
risus. Nunc et malesuada sem, id venenatis massa. Integer dolor ante, max=
imus in eleifend nec, ultricies ut risus. Mauris posuere eget tortor at p=
orttitor.=0AIn porta elementum ornare. Suspendisse aliquam, tortor sed al=
iquam bibendum, nulla ante rhoncus elit, placerat accumsan augue nibh non=
 est. Duis finibus vel tortor finibu)
1 OK Fetch completed (0.073 + 0.000 + 0.072 secs).


Sekitar 100 milidetik dan kami sudah melihat beberapa isi surat itu! Ini hanya hasil yang sangat baik, mengingat bahwa sebelumnya kami butuh hampir 4 detik untuk mengunduh konten satu huruf. Kemudian Anda cukup memuat seluruh isi surat dalam aliran latar belakang, dari luar akan tampak bahwa surat-surat itu dimuat secara instan. Yang diperlukan hanyalah melihat struktur surat dan mengunduh hanya apa yang diperlukan untuk tampilan cepat. 
Hanya satu saat. Permintaan ini akan membuat pesan di server muncul sebagai telah dibaca. Tetapi Anda dapat memperbaikinya dengan menambahkan hanya MENGINTIP ke permintaan tubuh

1 fetch 18871 (BODY.PEEK[1.1]<0.1024>)
* 18871 FETCH (BODY[1.1]<0> {1024}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus consecte=
tur enim in nisi venenatis, id varius tellus viverra. Praesent et enim te=
llus. Nunc vestibulum diam tortor, id posuere turpis tempor luctus. Vivam=
us molestie non nunc nec placerat. Cras finibus ut erat et tristique. Cur=
abitur vitae commodo risus. Etiam sed scelerisque erat. Quisque cursus bl=
andit finibus. Nullam ac lectus accumsan, molestie quam non, mollis urna.=
 Nulla at arcu in libero condimentum mollis ut non velit. Vestibulum sed =
risus et magna congue iaculis. Vestibulum nec interdum elit, ut commodo m=
auris. Nulla ipsum leo, vestibulum nec ligula non, elementum ullamcorper =
risus. Nunc et malesuada sem, id venenatis massa. Integer dolor ante, max=
imus in eleifend nec, ultricies ut risus. Mauris posuere eget tortor at p=
orttitor.=0AIn porta elementum ornare. Suspendisse aliquam, tortor sed al=
iquam bibendum, nulla ante rhoncus elit, placerat accumsan augue nibh non=
 est. Duis finibus vel tortor finibu)
1 OK Fetch completed (0.001 + 0.000 secs).


Dan voila! Surat itu masih belum dibaca dan beberapa konten yang kami terima.
Semuanya menjadi lebih mudah jika fitur permintaan PREVIEW diimplementasikan di server Anda. 

1 fetch 18871 (PREVIEW)
* 18871 FETCH (PREVIEW (FUZZY "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus consectetur enim in nisi venenatis, id varius tellus viverra. Praesent et enim tellus. Nunc vestibulum diam tortor, id posuere turpis t"))
1 OK Fetch completed (0.001 + 0.000 secs).


Di sini kami tidak menghabiskan waktu untuk menanyakan struktur sama sekali dan kami mendapatkan pratinjau pesan secara instan. Tapi jangan lupa bahwa struktur kueri berguna untuk mendefinisikan lampiran sehingga tidak dimuat ke dalam idle.

Tunggu


Hampir semua klien email mengimplementasikan tombol "segarkan" jika pengguna ingin menerima surat baru sekarang. Tapi entah kenapa ini tidak keren untuk zaman kita, di mana ada notifikasi baik di perangkat maupun di browser. Apa yang dikatakan IMAP tentang ini? Dan dia mengatakan IDLE . Operasi ini memegang koneksi ke folder dan memberi tahu Anda tentang perubahan ke folder. Harap dicatat, bukan kotak surat, tetapi folder. Untuk melakukan ini, Anda memerlukan server untuk mengimplementasikan fitur IDLE. 

Pertama, pilih folder tempat server akan mengirimkan peringatan, dan kemudian aktifkan IDLE

1 SELECT Inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft $Forwarded $MDNSent \*)] Flags permitted.
* 18872 EXISTS
* 0 RECENT
* OK [UNSEEN 18685] First unseen.
* OK [UIDVALIDITY 1532079879] UIDs valid
* OK [UIDNEXT 20155] Predicted next UID
* OK [HIGHESTMODSEQ 26338] Highest
1 OK [READ-WRITE] Select completed (0.002 + 0.000 + 0.001 secs).
1 IDLE
+ idling


Jawaban "+ idling" memberi tahu tentang dimasukkannya idle di folder. Apa yang terjadi jika surat baru tiba?

* 18873 EXISTS
* 1 RECENT


Saya mengirim sendiri surat yang sama, dan Idle memberi tahu saya bahwa saya harus meminta surat 18873, bahwa ada 18873 surat di folder itu, dan satu surat baru saja tiba.
Selanjutnya, saya akan meminta surat ini di koneksi lain, kami tertarik pada surat dengan jawaban ADA.

1 fetch 18873 (BODY.PEEK[1.1]<0.1024>)
* 18873 FETCH (BODY[1.1]<0> {1024}
---- Original Message ---- Tue, Apr 7, 2020, 17:11=0ASubject=
: Lorem Ipsum=0A  Lorem ipsum dolor sit amet, consectetur adipiscing elit=
. Vivamus consectetur enim in nisi venenatis, id varius tellus viverra. P=
raesent et enim tellus. Nunc vestibulum diam tortor, id posuere turpis te=
mpor luctus. Vivamus molestie non nunc nec placerat. Cras finibus ut erat=


Sangat penting untuk dipahami. IDLE membutuhkan koneksi terpisah, sehingga Anda tidak dapat menerima perubahan dan meminta pesan di sesi yang sama.
Apa lagi yang bisa dilakukan IDLE? Dia dapat memberi tahu tentang surat dan surat yang dihapus yang benderanya telah berubah. Mari kita lihat surat demi contoh, dengan demikian meletakkan bendera "/ terlihat" di atasnya dan menghapus surat itu.

* 18873 FETCH (FLAGS (\Seen \Recent))
* OK Still here
* OK Still here
* 18873 EXPUNGE
* 18871 EXPUNGE
* 0 RECENT


Saya menghapus percakapan (18873, 18871) dan melihat surat lain (respons FETCH). Mengapa surat ini menjadi 18871? Karena IMAP menceritakan nomor surat jika ada sesuatu yang berubah. Karena menjadi yang teratas, jumlahnya juga berubah. 
Dengan IDLE, kami dapat dengan cepat menyinkronkan keadaan kotak, tetapi tidak menyenangkan karena memerlukan koneksi terpisah. Mungkinkah ini lebih baik? Itu sebabnya saya di sini.

Teriak bagaimana kabar Anda


Bagaimana jika saya memberi tahu Anda bahwa ada fitur yang memungkinkan Anda menerima pemberitahuan dari server dalam koneksi yang sama, dan bahkan dikonfigurasikan secara khusus untuk kotak surat, dan bahkan tidak satu. Kedengarannya seperti dongeng, tetapi jangan menjadi gila, ini adalah kemampuan nyata MEMPERHATIKAN . Dia tahu banyak, misalnya:

  • Konfigurasikan folder tertentu dari mana kami mengharapkan pemberitahuan
  • Dengarkan perubahan status folder (baca huruf, huruf baru)
  • Atur format pemberitahuan, yaitu, apa yang ingin kita lihat saat mengganti folder
  • Dengarkan perubahan nama folder
  • Dengarkan perubahan metadata folder


Mari kita lihat contoh bagaimana kita dapat mendengarkan perubahan status folder

1 notify set (inboxes (MessageNew FlagChange MessageExpunge))
1 OK NOTIFY completed (0.001 + 0.000 secs).


Sekarang server akan mengirimkan pemberitahuan kepada kami dengan status folder, misalnya, saya akan menambahkan beberapa pesan ke folder yang berbeda

* STATUS INBOX/Ozon (MESSAGES 312 UIDNEXT 321 UNSEEN 48)
* STATUS "INBOX/Company News" (MESSAGES 178 UIDNEXT 179 UNSEEN 1)
* STATUS "INBOX/Company News" (MESSAGES 177 UIDNEXT 179 UNSEEN 0)


Saya akan menganalisis perintah:
Pertama datang perintah SET NOTIFY. Selanjutnya, dalam tanda kurung, kita memilih folder mana yang akan kita dengarkan:

  • Kotak masuk - untuk semua folder yang dapat Anda pilih
  • Pribadi - folder yang ada dalam ruang nama pengguna
  • Berlangganan - folder tempat pengguna berlangganan
  • Subtree - subtree folder yang akan ditentukan
  • Kotak surat - di sini Anda dapat membuat daftar folder untuk didengarkan.
  • Dipilih - hanya peringatan untuk folder yang dipilih


Dan parameter yang bertanggung jawab untuk filter peringatan:

  • MessageNew - jika pesan baru tiba
  • FlagChange - jika bendera telah berubah
  • MessageExpunge - jika pesan itu dihapus atau dipindahkan


Tetapi dengan perintah seperti itu, kami tidak dapat menerima parameter dari pesan baru, yang diubah, atau dihapus. Untuk melakukan ini, pilih parameter yang Dipilih dan tentukan apa yang harus dikembalikan. Kami dapat menambahkan lansiran lain tanpa menghapus yang sebelumnya.

1 notify set status (selected (MessageNew (uid preview) MessageExpunge))


Di sini, di dalam MessageNew, kami menentukan parameter yang harus dikembalikan oleh notifikasi. Saya akan memilih Kotak Masuk dan lagi saya akan melemparkan ke diri sendiri lorem ipsum.

* 18868 FETCH (UID 20157 PREVIEW (FUZZY "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus consectetur enim in nisi venenatis, id varius tellus viverra. Praesent et enim tellus. Nunc vestibulum diam tortor, id posuere turpis t"))


Apa kabar? Untuk idle, kita perlu menyimpan dua koneksi, yang salah satunya juga meminta pesan yang dikembalikan kepada kita. Segera mereka membawa kita semua di piring perak. 
Jadi kita bisa mendengarkan perubahan nama folder

1 notify set (inboxes (MailboxName))


Ganti nama beberapa folder dan lihat hasilnya.

* LIST () "/" 1111 ("OLDNAME" (aaaa))


Dan sekarang kita tahu bahwa ada folder "aaaa", dan menjadi "1111"
Sekarang Anda dapat mendengarkan perubahan bendera dan penghapusan pesan. Untuk melakukan ini, gunakan parameter FlagChange

1 notify set (selected (MessageNew (uid) FlagChange MessageExpunge))


Dan ketika Anda mengubah bendera pesan dan menghapusnya, kami mendapatkannya

* 18865 EXPUNGE
* 18864 FETCH (FLAGS ())
* 18864 FETCH (FLAGS (\Answered))


Apa berikutnya


Semua fitur ini membantu klien email untuk bekerja secepat dan senyaman mungkin bagi pengguna. IDLE dan NOTIFY memberi tahu pengguna tentang perubahan dalam folder, meminta bagian dari surat mempercepat pemuatannya. 
Pada artikel terakhir, saya ingin berbicara tentang mekanisme pencarian di IMAP dan bagaimana hal itu dapat dipercepat dan mengurangi beban pada jaringan. Terima kasih sudah membaca sampai akhir. 

All Articles