Pengenalan WebSockets dengan Spring

1. Gambaran keseluruhan

Dalam artikel ini, kami akan membuat aplikasi web sederhana yang menerapkan pemesejan menggunakan kemampuan WebSocket baru yang diperkenalkan dengan Spring Framework 4.0.

WebSockets adalah hubungan dua arah , dupleks penuh , berterusan antara penyemak imbas web dan pelayan. Setelah sambungan WebSocket dibuat, sambungan tetap terbuka sehingga pelanggan atau pelayan memutuskan untuk menutup sambungan ini.

Kes penggunaan biasa mungkin berlaku ketika aplikasi melibatkan banyak pengguna berkomunikasi antara satu sama lain, seperti dalam chat. Kami akan membina pelanggan sembang sederhana dalam contoh kami.

2. Pergantungan Maven

Oleh kerana ini adalah projek berasaskan Maven, pertama kami menambahkan kebergantungan yang diperlukan ke pom.xml :

 org.springframework spring-websocket 5.2.2.RELEASE   org.springframework spring-messaging 5.2.2.RELEASE 

Sebagai tambahan, kerana kita akan menggunakan JSON untuk membina badan mesej kita, kita perlu menambahkan pergantungan Jackson . Ini membolehkan Spring menukar objek Java kami ke / dari JSON :

 com.fasterxml.jackson.core jackson-core 2.10.2   com.fasterxml.jackson.core jackson-databind 2.10.2 

Sekiranya anda ingin mendapatkan versi terbaru perpustakaan di atas, cari di Maven Central.

3. Aktifkan WebSocket pada musim bunga

Perkara pertama yang perlu dilakukan ialah mengaktifkan keupayaan WebSocket. Untuk melakukan ini, kita perlu menambahkan konfigurasi pada aplikasi kita dan memberi penjelasan pada kelas ini dengan @EnableWebSocketMessageBroker .

Seperti namanya, ini membolehkan pengendalian mesej WebSocket, disokong oleh broker mesej:

@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat"); registry.addEndpoint("/chat").withSockJS(); } } 

Di sini, kita dapat melihat bahawa kaedah configureMessageBroker digunakan untuk mengkonfigurasi broker mesej . Pertama, kami membolehkan broker mesej dalam memori membawa kembali mesej kepada pelanggan di destinasi yang diawali dengan "/ topic".

Kami melengkapkan konfigurasi mudah kami dengan menetapkan awalan "/ aplikasi" untuk menyaring destinasi yang menyasarkan kaedah anotasi aplikasi (melalui @MessageMapping ).

The registerStompEndpoints Cara mendaftarkan "/ chat" titik akhir, membolehkan sokongan STOMP Spring . Perlu diingat bahawa kami juga menambahkan di sini titik akhir yang berfungsi tanpa SockJS demi keanjalan.

Titik akhir ini, apabila diawali dengan “/ app”, adalah titik akhir yang digunakan kaedah ChatController.send () dipetakan untuk dikendalikan.

Ini juga membolehkan pilihan penggantian SockJS, sehingga pilihan pemesejan alternatif dapat digunakan jika WebSockets tidak tersedia. Ini berguna kerana WebSocket belum disokong di semua penyemak imbas dan mungkin dihalang oleh proksi rangkaian yang terhad.

Kekurangan membolehkan aplikasi menggunakan WebSocket API tetapi menurunkan dengan baik ke alternatif bukan WebSocket apabila perlu pada waktu runtime.

4. Buat Model Mesej

Sekarang setelah kita menyiapkan projek dan mengkonfigurasi kemampuan WebSocket, kita perlu membuat mesej untuk dihantar.

Titik akhir akan menerima mesej yang mengandungi nama pengirim dan teks dalam mesej STOMP yang badannya adalah objek JSON .

Mesej mungkin kelihatan seperti ini:

{ "from": "John", "text": "Hello!" } 

Untuk memodelkan pesan yang membawa teks, kita dapat membuat yang mudahObjek Java dengan dari dan teks hartanah:

public class Message { private String from; private String text; // getters and setters } 

Secara lalai, Spring akan menggunakan perpustakaan Jackson untuk menukar objek model kami ke dan dari JSON.

5. Buat Pengawal Pengendalian Mesej

Seperti yang telah kita lihat, pendekatan Spring untuk bekerja dengan pemesejan STOMP adalah mengaitkan kaedah pengawal dengan titik akhir yang dikonfigurasi. Ini dimungkinkan melalui anotasi @MessageMapping .

Perkaitan antara titik akhir dan pengawal memberi kita keupayaan untuk menangani mesej jika diperlukan:

@MessageMapping("/chat") @SendTo("/topic/messages") public OutputMessage send(Message message) throws Exception { String time = new SimpleDateFormat("HH:mm").format(new Date()); return new OutputMessage(message.getFrom(), message.getText(), time); } 

F atau tujuan contoh kami, kami akan membuat objek model lain bernama OutputMessage untuk mewakili mesej output yang dihantar ke destinasi yang dikonfigurasi. Kami mengisi objek kami dengan pengirim dan teks mesej yang diambil dari mesej masuk dan memperkayakannya dengan cap waktu.

Setelah mengendalikan mesej kami, kami menghantarnya ke destinasi yang sesuai yang ditentukan dengan anotasi @SendTo . Semua pelanggan ke destinasi " / topic / message" akan menerima mesej tersebut.

6. Buat Pelanggan Penyemak Imbas

Setelah membuat konfigurasi kami di sisi pelayan, kami akan menggunakan perpustakaan sockjs-client untuk membina halaman HTML ringkas yang berinteraksi dengan sistem pesanan kami.

Pertama sekali, kita perlu mengimport sockjs dan dipijak perpustakaan pelanggan Javascript. Seterusnya, kita dapat membuat fungsi connect () untuk membuka komunikasi dengan endpoint kita, fungsi sendMessage () untuk menghantar mesej STOMP kita dan fungsi disconnect () untuk menutup komunikasi:

  Chat WebSocket    var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; document.getElementById('response').innerHTML = ''; } function connect() { var socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/messages', function(messageOutput) { showMessageOutput(JSON.parse(messageOutput.body)); }); }); } function disconnect() { if(stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } function sendMessage() { var from = document.getElementById('from').value; var text = document.getElementById('text').value; stompClient.send("/app/chat", {}, JSON.stringify({'from':from, 'text':text})); } function showMessageOutput(messageOutput) { var response = document.getElementById('response'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.appendChild(document.createTextNode(messageOutput.from + ": " + messageOutput.text + " (" + messageOutput.time + ")")); response.appendChild(p); }

Connect Disconnect

Send

7. Menguji Contoh

Untuk menguji contoh kami, kami dapat membuka beberapa tetingkap penyemak imbas dan mengakses halaman sembang di:

//localhost:8080

Setelah ini selesai, kita dapat bergabung dengan sembang dengan memasukkan nama panggilan dan menekan butang sambung. Sekiranya kita menulis dan menghantar mesej, kita dapat melihatnya dalam semua sesi penyemak imbas yang telah menyertai sembang.

Lihat tangkapan skrin untuk melihat contoh:

8. Kesimpulannya

Dalam tutorial ini, kami telah menerokai sokongan WebSocket Spring. Kami telah melihat konfigurasi sisi pelayannya dan membina rakan pelanggan yang mudah dengan penggunaan sockjs dan stomp perpustakaan Javascript.

Contoh kod boleh didapati dalam projek GitHub.