Apakah kinerja satu-satunya alasan untuk tidak menggunakan SignalR (websockets) sepenuhnya sebagai pengganti API REST tradisional?

42

Saya telah digunakan SignalRuntuk mencapai fungsionalitas pengiriman pesan langsung di beberapa proyek saya. Tampaknya bekerja dengan andal dan sangat mudah dipelajari untuk digunakan.

Godaan, setidaknya bagi saya, adalah meninggalkan pengembangan layanan Web API dan gunakan SignalRuntuk semuanya.

Saya merasa ini bisa dicapai dengan desain yang bijaksana, dan jika ya, itu berarti jauh lebih sedikit kode klien yang diperlukan. Lebih penting lagi, itu akan berarti bahwa akan ada satu antarmuka untuk layanan daripada antarmuka terpisah, dan dalam kasus terburuk, bahwa seseorang dapat menghubungkan ini tanpa memikirkan kapan hal-hal ditampilkan, dll.

Jadi, saya ingin tahu:

  1. Apakah ada alasan lain untuk tidak menggunakan SignalR sebagai pengganti semua layanan web selain kinerja?
  2. Apakah kinerja SignalR cukup memprihatinkan sehingga tidak masuk akal untuk melakukannya?

Sudah lama menjadi impian saya untuk dapat menerjemahkan objek sisi server dan definisi layanan ke kode akses layanan sisi klien tanpa sesuatu yang konyol seperti node.js. Misalnya, jika saya mendefinisikan objek yang menarik InterestingObjectdan layanan ke CRUDobjek tersebut InterestingObjectService, saya dapat menentukan rute URL standar ke layanan - katakan, "/ {serviceName} / {methodName}" - tetapi saya masih perlu menulis kode klien untuk mengakses pelayanan. Karena objek akan diteruskan dari klien ke server dan kembali, tidak ada alasan praktis untuk memilikinyauntuk mendefinisikan objek secara eksplisit dalam kode sisi klien, dan juga tidak perlu secara eksplisit menentukan rute untuk melakukan operasi CRUD. Saya merasa seperti harus ada cara untuk membakukan semua ini sehingga memungkinkan untuk menulis klien dengan asumsi bahwa akses layanan berfungsi dari klien ke server dan kembali secara transparan seperti ketika saya menulis WinForms atau Java Applet atau Aplikasi Asli atau apa pun.

Jika SignalR cukup baik untuk digunakan sebagai pengganti layanan web tradisional, itu mungkin cara yang layak untuk mencapai ini. SignalR sudah menyertakan fungsionalitas untuk membuat hub berfungsi seperti layanan yang saya jelaskan, sehingga saya bisa mendefinisikan layanan common base (CRUD) yang akan menawarkan semua fungsionalitas ini di luar kotak dengan beberapa refleksi. Kemudian saya hampir dapat menerima akses layanan yang diberikan, menyelamatkan saya dari gangguan penulisan ulang kode untuk mengakses sesuatu yang dapat diakses dengan konvensi - dan yang lebih penting, waktu saya harus menghabiskan kode menulis untuk menentukan bagaimana ini diperbarui di DOM.

Setelah membaca hasil edit saya, saya merasa sedikit tidak masuk akal, jadi silakan bertanya kepada saya jika Anda memiliki pertanyaan tentang apa yang saya maksud. Pada dasarnya, saya ingin akses layanan setransparan mungkin.

tacos_tacos_tacos
sumber
5
Jika Anda memiliki kartu jaringan magis yang dapat membuka soket dengan jumlah tak terbatas dan jaringan magis yang dapat mendukung bandwidth dengan jumlah tak terbatas dan server magis yang memiliki jumlah memori dan siklus cpu yang tak terbatas, maka hanya soket web merupakan pilihan yang tepat!
CSA melakukan apa yang Anda inginkan, objek bisnis dapat bergerak sendiri antara klien dan server.
Andy

Jawaban:

50

Kedua teknologi tersebut memiliki tujuan yang sangat berbeda.

  • REST untuk panggilan biasa ke API, dengan klien menjadi aktor aktif dari pertukaran. Ketika klien perlu menemukan koordinat GPS dari suatu alamat, klien memulai panggilan ke API dan menunggu sampai menerima koordinat, atau kesalahan terjadi, atau waktu habis berlalu.

  • Soket web adalah untuk segala sesuatu yang perlu melakukan hal-hal yang berlawanan. Misalnya, ketika saya menggunakan situs web intranet yang menunjukkan kepada saya secara real time log dan kinerja server yang berbeda, klien mungkin pasif dan menunggu sampai server mengiriminya pesan log yang baru diterbitkan atau metrik kinerja.

Perbedaannya jelas: dalam kasus pertama, klien memutuskan kapan ia membutuhkan informasi tertentu; dalam kasus kedua, klien hanya menunggu untuk dihubungi, dan mungkin tidak tahu kapan akan dihubungi.

Dalam beberapa cara, keduanya dapat dipertukarkan: Anda dapat menerapkan soket web saat Anda tidak membutuhkannya (yaitu klien akan memanggil server melalui soket web alih-alih membuat panggilan REST) ​​dan Anda dapat menggunakan polling atau polling panjang sebagai pengganti soket web (mengingat bahwa ini digunakan dengan sukses selama bertahun-tahun sampai soket web menjadi sangat populer).

Tetapi pertukaran mereka membutuhkan biaya:

  • Saat Anda menggunakan polling atau polling panjang alih-alih soket web, Anda sering membuang-buang bandwidth.

  • Ketika Anda menggunakan soket web untuk melakukan apa yang dapat dilakukan melalui api web, Anda tetap membuka semua koneksi dari semua klien aktif, yang mungkin bukan yang Anda inginkan. Untuk situs web kecil tempat Anda berharap memiliki paling banyak 5 klien pada saat bersamaan, ini bukan masalah. Untuk layanan seperti Amazon AWS, ini tidak akan mudah dipecahkan secara teknis.

Jangan gunakan soket web saat Anda tidak membutuhkannya. Untuk mendapatkan koordinat GPS dari suatu alamat, saya tidak memperoleh apa-apa dalam membuka koneksi soket web, melakukan panggilan, menunggu jawaban dan menutup koneksi: REST memenuhi kebutuhan saya untuk skenario seperti itu.

  • Jika Anda menemukan diri Anda berulang kali dan sering memeriksa informasi melalui panggilan REST ke suatu layanan, ini mungkin pertanda baik bahwa Anda harus pindah ke soket web. Demikian pula, Stack Overflow mengurangi penggunaan bandwidth dengan menggunakan soket web, karena ini membantu orang untuk tidak menghabiskan waktu mereka menekan F5 di halaman rumah untuk melihat apakah mereka memiliki pesan baru.

  • Jika Anda menemukan Anda membuka koneksi soket web, gunakan itu untuk melakukan satu panggilan, dan kemudian tutup, atau jika koneksi Anda tetap terbuka tetapi server mengirimkan sesuatu ke klien hanya atas permintaan klien, beralihlah ke REST.

Soket web juga masih memiliki dukungan terbatas dan tidak selalu mudah diterapkan. Walaupun SignalR membuatnya mudah untuk diimplementasikan, ini tidak berarti bahwa Anda tidak akan mengalami kesulitan untuk mengimplementasikannya dalam bahasa / konteks / lingkungan lain. Dengan REST, itu mudah: itu mungkin curlpanggilan atau fitur serupa yang tersedia di setiap bahasa utama. Dengan soket web, Anda tidak dapat memastikan berapa lama untuk membuat klien menggunakan [masukkan nama bahasa yang belum Anda ketahui di sini].

Saya telah menggunakan soket web di beberapa proyek di .NET, Python dan node.js.

  • Di. NET, itu tidak terlalu sulit, tapi tetap saja, saya masih menghabiskan beberapa hari untuk mencari tahu beberapa masalah samar, seperti koneksi turun segera setelah dibuka. (Ini sebelum SignalR; Saya tidak pernah mencoba SignalR). Saya juga menggunakan WCF dalam mode soket web, yang juga bukan tanpa masalah (tapi saya percaya bahwa WCF selalu disertai masalah).

  • Di node.js, ini bisa dilakukan, tapi saya harus beralih dua kali perpustakaan sampai saya menemukan yang berfungsi. Saya percaya saya telah menghabiskan setidaknya seminggu mencoba membuat soket web Hello World.

  • Dengan Python, saya mencoba sekali, menghabiskan dua atau tiga hari, dan ditinggalkan. Itu tidak pernah berhasil.

Bandingkan ini dengan REST: satu-satunya masalah yang dapat dihadapi seseorang dengan bahasa / kerangka kerja baru adalah mengetahui cara mengirim file POST atau menerima respons biner yang sangat besar. Saya ingat menghabiskan beberapa jam mencari solusi untuk beberapa bahasa. Namun, beberapa jam untuk kasus khusus tidak ada artinya dibandingkan dengan hari atau minggu untuk Hello World yang sederhana.

Arseni Mourzenko
sumber
2
Terbarui jawaban Anda, MainMa, karena menurut saya itu menarik / bermanfaat. Ada satu hal yang saya tidak mengerti. Anda menyebutkan bahwa sejumlah kecil klien tidak masalah untuk menangani soket web (mis., Paling banyak 5 pada saat yang sama). Kemudian Anda menyebutkan StackOverflow menggunakan soket web di beranda mereka. Bagaimana mereka menangani jumlah pengguna yang begitu tinggi? Saya bertanya karena saya mencoba 20+ koneksi SignalR dan saya menemukan penundaan pesan perlahan mulai meningkat, sebelum semuanya hancur (semuanya tidak responsif).
gnychis
1
@ gnychis: ada banyak solusi untuk itu, tetapi banyak dari mereka yang lebih terkait dengan infrastruktur itu sendiri (itulah gunanya serverfault.com ). Secara umum, letakkan lebih banyak perangkat keras dan bagi pengguna di antara domain, sehingga beberapa koneksi ditangani oleh sockets1.example.com, lainnya oleh sockets2.example.com, dll. Cukup efektif tetapi juga cukup mahal dalam hal perangkat keras dan bandwidth.
Arseni Mourzenko
3
Jawaban ini sangat bagus, tetapi saya ingin mempersempit pertanyaan aslinya. Jika aplikasi memerlukan koneksi websocket yang berkelanjutan, lalu mengapa tidak menggunakan websockets sepenuhnya sebagai pengganti REST API? Karena websocket terbuka, mungkin harus dimanfaatkan sepenuhnya.
HappyNomad
Saya baru saja menemukan jawaban untuk pertanyaan saya sendiri.
HappyNomad
1

Hanya 2 sen saya ...

Saya pikir ini bukan tentang kinerja atau apa pun. Ini tentang standar. REST adalah standar dan IMHO memiliki keunggulan sebagai berikut:

  • Permintaan HTTP mudah digunakan. Semua orang dapat dengan cepat menggunakan API REST. Heck, Anda bahkan dapat membuka browser dan mengetik URL untuk melihat data, seberapa interaktif Anda?
  • (Hampir) bahasa pemrograman apa pun dapat menggunakannya. Ini semacam antarmuka universal. Berinteraksi dengan SignalR dari bahasa yang eksotis tampaknya kurang jelas.
  • Ini memiliki dukungan perkakas yang bagus, seperti http://petstore.swagger.wordnik.com/
  • Ini adalah "antarmuka" yang bagus untuk debug. Anda dapat dengan mudah memonitor pesan yang masuk dan keluar secara langsung di browser, melihat data, dll. Dengan soket web dan pustaka khusus, tidak begitu jelas, Anda harus secara eksplisit mencatat semuanya.
dagnelies
sumber
1
Meskipun Anda membuat beberapa poin bagus tentang REST API menjadi sedikit lebih mudah dan mungkin memiliki tooling yang lebih baik, jawaban ini mengatakan beberapa hal yang memang tidak benar. REST bukan standar , sedangkan WebSockets adalah .
StriplingWarrior
1
Saya kira itu adalah kata-kata yang buruk dari bagian saya. Apa yang saya maksud dengan "standar" adalah hal biasa, banyak digunakan, cara standar dalam melakukan sesuatu ... dan bukan "menjadi Standar RFC".
dagnelies
Klarifikasi yang bagus. Dan, btw, Chrome setidaknya memungkinkan Anda untuk melihat lalu lintas WebSockets dalam perangkat pengembangnya. Saya membayangkan browser lain mungkin juga melakukannya.
StriplingWarrior