Membuat Websocket yang andal dengan subprotokola

Ketika koneksi klien Websocket terputus karena masalah jaringan terputus-putus, pesan dapat hilang. Dalam sistem pub/sub, penerbit dipisahkan dari pelanggan, sehingga penerbit mungkin tidak mendeteksi koneksi pelanggan yang hilang atau kehilangan pesan. Sangat penting bagi klien untuk mengatasi masalah jaringan terputus-putus dan mempertahankan pengiriman pesan yang andal. Untuk mencapainya, Anda dapat membuat klien Websocket yang andal dengan bantuan subprotokel Azure Web PubSub yang andal.

Reliable Protocol

Layanan Web PubSub mendukung dua subprotokola json.reliable.webpubsub.azure.v1 yang andal dan protobuf.reliable.webpubsub.azure.v1. Klien harus mengikuti bagian penerbit, pelanggan, dan pemulihan subprotokul untuk mencapai keandalan. Gagal menerapkan subprotokol dengan benar dapat mengakibatkan pengiriman pesan tidak berfungsi seperti yang diharapkan atau layanan menghentikan klien karena pelanggaran protokol.

Cara Mudah - Gunakan SDK Klien

Cara paling sederhana untuk membuat klien yang andal adalah dengan menggunakan SDK Klien. SDK Klien mengimplementasikan spesifikasi klien Web PubSub dan menggunakan json.reliable.webpubsub.azure.v1 secara default. Silakan merujuk ke Terbitkan/berlangganan di antara klien untuk memulai dengan cepat.

Cara Keras - Terapkan dengan tangan

Tutorial berikut memandikan Anda melalui bagian penting dari penerapan spesifikasi klien Web PubSub. Panduan ini bukan untuk orang yang mencari awal yang cepat tetapi yang ingin mengetahui prinsip mencapai keandalan. Untuk memulai cepat, silakan gunakan SDK Klien.

Inisialisasi

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

  • Gunakan subprotokola andal Json:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "json.reliable.webpubsub.azure.v1"
    );
    
  • Gunakan protobuf reliable subprotocol:

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

pemulihan Koneksi

pemulihan Koneksi adalah dasar untuk mencapai keandalan dan harus diimplementasikan saat menggunakan json.reliable.webpubsub.azure.v1 protokol dan protobuf.reliable.webpubsub.azure.v1 .

Koneksi Websocket mengandalkan TCP. Ketika koneksi tidak hilang, pesan tidak hilang dan dikirimkan secara berurutan. Untuk mencegah kehilangan pesan atas koneksi yang terputus, layanan Web PubSub mempertahankan informasi status koneksi, termasuk informasi grup dan pesan. Informasi ini digunakan untuk memulihkan klien pada pemulihan koneksi

Ketika klien terhubung kembali ke layanan menggunakan subprotokola yang andal, klien akan menerima pesan yang Connected berisi connectionId dan reconnectionToken. connectionId Mengidentifikasi sesi koneksi dalam layanan.

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

Setelah koneksi WebSocket terputus, klien harus mencoba terhubung kembali dengan yang sama connectionId untuk memulihkan sesi yang sama. Klien tidak perlu bernegosiasi dengan server dan mendapatkan access_token. Sebagai gantinya, untuk memulihkan koneksi, klien harus membuat permintaan koneksi WebSocket langsung ke layanan dengan nama host layanan, connection_id, dan reconnection_token:

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

pemulihan Koneksi mungkin gagal jika masalah jaringan belum dipulihkan. Klien harus terus mencoba kembali untuk menyambungkan kembali hingga:

  1. Koneksi Websocket ditutup dengan kode status 1008. Kode status berarti connectionId telah dihapus dari layanan.
  2. Kegagalan pemulihan terus terjadi selama lebih dari 1 menit.

Publisher

Klien yang mengirim peristiwa ke penanganan aktivitas atau menerbitkan pesan ke klien lain disebut penerbit. Penerbit harus mengatur ackId dalam pesan untuk menerima pengakuan dari layanan Web PubSub yang menerbitkan pesan berhasil atau tidak.

ackId adalah pengidentifikasi pesan, setiap pesan baru harus menggunakan ID unik. Aslinya ackId harus digunakan saat mengirim ulang pesan.

Contoh grup mengirim pesan:

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

Sampel respons ack:

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

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

Ketika layanan mengalami kesalahan internal sementara dan pesan tidak dapat dikirim ke pelanggan, penerbit akan menerima ack dengan success: false. Penerbit harus membaca kesalahan untuk menentukan apakah akan mengirim ulang pesan atau tidak. Jika pesan ditolak, hal yang sama ackId harus digunakan.

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

Message Failure

Jika respons ack layanan hilang karena koneksi WebSocket terputus, penerbit harus mengirim ulang pesan dengan hal yang sama ackId setelah pemulihan. Ketika pesan sebelumnya diproses oleh layanan, pesan akan mengirim ack yang Duplicate berisi kesalahan. Penerbit harus berhenti mengirim ulang pesan ini.

{
  "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 dari penanganan aktivitas atau penerbit disebut pelanggan. Ketika koneksi terputus karena masalah jaringan, layanan Web PubSub tidak tahu berapa banyak pesan yang dikirim ke pelanggan. Untuk menentukan pesan terakhir yang diterima oleh pelanggan, layanan mengirim pesan data yang sequenceIdberisi . Pelanggan merespons dengan pesan ack urutan:

Sampel urutan ack:

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

sequenceId adalah nomor inkremental uint64 dalam sesi connection-id. Pelanggan harus merekam yang terbesar sequenceId yang telah diterimanya, hanya menerima pesan dengan pesan yang lebih besar sequenceId, dan menghilangkan pesan dengan pesan yang lebih kecil atau sama dengan sequenceId. Pelanggan harus kurang dengan yang terbesar sequenceId yang direkam, sehingga layanan dapat melewati pesan redelivering yang telah diterima pelanggan. Misalnya, jika pelanggan merespons dengan sequenceAck , sequenceId: 5layanan hanya akan mengirim ulang pesan dengan sequenceId lebih besar dari 5.

Semua pesan dikirimkan kepada pelanggan secara berurutan hingga koneksi WebSocket terputus. Dengan sequenceId, layanan dapat mengetahui berapa banyak pelanggan pesan yang telah diterima di seluruh koneksi WebSocket dalam sesi. Setelah koneksi WebSocket terputus, layanan akan mengirim kembali pesan yang tidak diakui oleh pelanggan. Layanan ini menyimpan sejumlah pesan yang tidak diakui secara terbatas. Ketika jumlah pesan melebihi batas, layanan akan menutup koneksi WebSocket dan menghapus sesi. Dengan demikian, pelanggan harus mengabaikan sesegera sequenceId mungkin.