Membuat Websocket yang andal dengan subprotokola

Koneksi klien Websocket mungkin hilang karena masalah jaringan terputus-terputus dan ketika koneksi terputus, pesan juga akan hilang. Dalam sistem pubsub, penerbit diputuskan dari pelanggan, sehingga penerbit sulit mendeteksi penurunan pelanggan atau kehilangan pesan. Sangat penting bagi klien untuk mengatasi masalah jaringan terputus-terputus dan menjaga keandalan pengiriman pesan. Untuk mencapai itu, Anda dapat membuat klien Websocket yang andal dengan bantuan subprotokola yang andal.

Catatan

Protokol yang andal masih dalam pratinjau. Beberapa perubahan diharapkan di masa mendatang.

Reliable Protocol

Layanan mendukung dua subprotokel json.reliable.webpubsub.azure.v1 yang andal dan protobuf.reliable.webpubsub.azure.v1. Klien harus mengikuti protokol, terutama termasuk bagian dari koneksi ulang, penerbit, dan pelanggan untuk mencapai keandalan, atau pengiriman pesan mungkin tidak berfungsi seperti yang diharapkan atau layanan dapat menghentikan klien karena melanggar spesifikasi protokol.

Inisialisasi

Untuk menggunakan subprotokol yang andal, Anda harus mengatur subprotokol saat membuat koneksi Websocket. Di JavaScript, Anda dapat menggunakan sebagai berikut:

  • Menggunakan subprotokola andal Json

    var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'json.reliable.webpubsub.azure.v1');
    
  • Menggunakan subprotokola andal Protobuf

    var pubsub = new WebSocket('wss://test.webpubsub.azure.com/client/hubs/hub1', 'protobuf.reliable.webpubsub.azure.v1');
    

Koneksi ulang

Koneksi websocket disampaikan pada TCP, jadi jika koneksi tidak terputus, semua pesan harus tidak hilang dan berurutan. Saat menghadapi masalah jaringan dan koneksi hilang, semua status seperti info grup dan pesan disimpan oleh layanan dan menunggu koneksi ulang pulih. Koneksi Websocket memiliki sesi dalam layanan dan pengidentifikasinya adalah connectionId. Koneksi ulang adalah dasar untuk mencapai keandalan dan harus diimplementasikan. Ketika koneksi baru tersambung ke layanan menggunakan subprotokel yang andal, koneksi akan menerima pesan yang Connected berisi connectionId dan reconnectionToken.

{
    "type":"system",
    "event":"connected",
    "connectionId": "<connection_id>",
    "reconnectionToken": "<reconnection_token>"
}

Setelah koneksi WebSocket terputus, klien harus terlebih dahulu mencoba menyambungkan kembali dengan yang sama connectionId untuk mempertahankan sesi. Klien tidak perlu bernegosiasi dengan server dan mendapatkan access_token. Sebagai gantinya, koneksi ulang harus membuat permintaan koneksi websocket ke layanan langsung dengan connection_id dan reconnection_token dengan uri berikut:

wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connection_id>&awps_reconnection_token=<reconnection_token>

Koneksi ulang mungkin gagal karena masalah jaringan belum dipulihkan. Klien harus terus mencoba kembali menyambungkan kembali hingga

  1. Koneksi Websocket ditutup dengan kode status 1008. Kode status berarti connectionId telah dihapus dari layanan.
  2. Kegagalan koneksi ulang membuat lebih dari 1 menit.

Publisher

Klien yang mengirim peristiwa ke penanganan aktivitas atau menerbitkan pesan ke klien lain disebut penerbit dalam dokumen. Penerbit harus mengatur ackId ke pesan untuk diakui dari layanan tentang apakah pesan berhasil diterbitkan atau tidak. Pesan ackId dalam adalah pengidentifikasi pesan, yang berarti pesan yang berbeda harus menggunakan pesan yang berbeda ackId, sementara mengirim ulang pesan harus tetap sama ackId agar layanan tidak diduplikasi.

Contoh grup mengirim pesan:

{
    "type": "sendToGroup",
    "group": "group1",
    "dataType" : "text",
    "data": "text data",
    "ackId": 1
}

Respons ack sampel:

{
    "type": "ack",
    "ackId": 1,
    "success": true
}

Jika layanan mengembalikan ack dengan success: true, pesan telah diproses oleh layanan dan klien dapat mengharapkan pesan akan dikirimkan kepada semua pelanggan.

Namun, Dalam beberapa kasus, Layanan memenuhi beberapa kesalahan internal sementara dan pesan tidak dapat dikirim ke pelanggan. Dalam kasus seperti itu, penerbit akan menerima ack seperti berikut dan harus mengirim ulang pesan dengan yang sama ackId jika diperlukan berdasarkan logika bisnis.

{
    "type": "ack",
    "ackId": 1,
    "success": false,
    "error": {
        "name": "InternalServerError",
        "message": "Internal server error"
    }
}

Message Failure

Ack layanan mungkin terputus karena koneksi WebSocket terputus. Jadi, penerbit harus mendapatkan pemberitahuan ketika koneksi Websocket turun dan mengirim ulang pesan dengan yang sama ackId setelah koneksi ulang. Jika pesan benar-benar telah diproses oleh layanan, pesan akan merespons ack dengan Duplicate dan penerbit harus berhenti mengirim ulang pesan ini lagi.

{
    "type": "ack",
    "ackId": 1,
    "success": false,
    "error": {
        "name": "Duplicate",
        "message": "Message with ack-id: 1 has been processed"
    }
}

Message duplicated

Pelanggan

Klien yang menerima pesan yang dikirim dari penanganan aktivitas atau penerbit disebut pelanggan dalam dokumen. Ketika koneksi terputus oleh masalah jaringan, layanan tidak tahu berapa banyak pesan yang benar-benar dikirim ke pelanggan. Jadi pelanggan harus memberi tahu layanan pesan mana yang telah diterima. Pesan Data berisi sequenceId dan pelanggan harus menutup urutan-id dengan pesan ack urutan:

Contoh ack urutan:

{
    "type": "sequenceAck",
    "sequenceId": 1
}

Sequence-id adalah nomor inkremental uint64 dengan-dalam sesi connection-id. Pelanggan harus merekam urutan-id terbesar yang pernah diterima dan menerima semua pesan dengan urutan-id yang lebih besar dan menghilangkan semua pesan dengan urutan yang lebih kecil atau sama dengan id urutan. Ack urutan mendukung ack kumulatif, yang berarti jika Anda ack sequence-id=5, layanan akan memperlakukan semua pesan dengan sequence-id yang lebih kecil dari 5 telah diterima oleh pelanggan. Pelanggan harus ack dengan urutan-id terbesar yang direkam, sehingga layanan dapat melewati pesan redelivering yang telah diterima pelanggan.

Semua pesan dikirimkan kepada pelanggan secara berurutan sampai koneksi WebSockets turun. Dengan sequence-id, layanan dapat memiliki pengetahuan tentang berapa banyak pesan yang benar-benar diterima pelanggan di seluruh koneksi WebSockets dengan-dalam sesi connection-id. Setelah koneksi WebSockets terputus, layanan akan mengirim ulang pesan yang harus dikirimkannya tetapi tidak di-ack-ed oleh pelanggan. Layanan menyimpan pesan yang tidak dibatasi dengan batas, jika pesan melebihi batas, layanan akan menutup koneksi WebSockets dan menghapus sesi connection-id. Dengan demikian, pelanggan harus mengabaikan urutan-id sesegera mungkin.