Contoh Pantas Anotasi @SendToUser Websockets Spring

1. Gambaran keseluruhan

Dalam tutorial ringkas ini, kita akan menggambarkan cara mengirim mesej ke sesi tertentu atau pengguna tertentu menggunakan Spring WebSockets .

Untuk pengenalan modul di atas, sila rujuk artikel ini.

2. Konfigurasi WebSocket

Pertama sekali, kita perlu mengkonfigurasi broker mesej dan titik akhir aplikasi WebSocket kami :

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

Dengan @EnableWebSocketMessageBroker kami mengaktifkan pesanan yang disokong oleh broker melalui WebSocket menggunakan STOMP , yang bermaksud Protokol Pemesejan Berorientasikan Teks Streaming. Penting untuk diperhatikan bahawa anotasi ini perlu digunakan bersama dengan @Configuration .

Tidak wajib memperluas AbstractWebSocketMessageBrokerConfigurer tetapi, sebagai contoh ringkas, lebih mudah untuk menyesuaikan konfigurasi yang diimport.

Pada kaedah pertama, kami menubuhkan broker pesanan berasaskan memori sederhana untuk membawa kembali pesan kepada klien di destinasi yang diawali dengan "/ topic" dan "/ queue" .

Dan, pada yang kedua, kami mendaftarkan titik akhir stomp pada "/ salam" .

Sekiranya kita mahu mengaktifkan SockJS, kita harus meminda bahagian daftar:

registry.addEndpoint("/greeting").withSockJS();

3. Dapatkan ID Sesi oleh Pemintas

Salah satu cara untuk mendapatkan id sesi adalah dengan menambahkan Spring Interceptor yang akan dicetuskan semasa berjabat tangan dan mendapatkan maklumat dari data permintaan.

Pemintas ini boleh ditambahkan terus di WebSocketConfig:

@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry .addEndpoint("/greeting") .setHandshakeHandler(new DefaultHandshakeHandler() { public boolean beforeHandshake( ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest .getServletRequest().getSession(); attributes.put("sessionId", session.getId()); } return true; }}).withSockJS(); }

4. Titik Akhir WebSocket

Bermula dengan Spring 5.0.5. SIARAN, tidak perlu melakukan penyesuaian kerana peningkatan anotasi @SendToUser , yang memungkinkan kami untuk menghantar mesej ke destinasi pengguna melalui " / user / {sessionId} / ... " daripada “ / user / {user} /… “.

Ini bermaksud anotasi berfungsi bergantung pada id sesi mesej input, dengan berkesan menghantar balasan ke destinasi peribadi ke sesi:

@Controller public class WebSocketController { @Autowired private SimpMessageSendingOperations messagingTemplate; private Gson gson = new Gson(); @MessageMapping("/message") @SendToUser("/queue/reply") public String processMessageFromClient( @Payload String message, Principal principal) throws Exception { return gson .fromJson(message, Map.class) .get("name").toString(); } @MessageExceptionHandler @SendToUser("/queue/errors") public String handleException(Throwable exception) { return exception.getMessage(); } }

Adalah penting untuk menyatakan bahawa, @SendToUser menunjukkan bahawa nilai pengembalian kaedah pengendalian mesej harus dihantar sebagai Mesej ke destinasi yang ditentukan yang disertakan dengan " / user / {username} " .

5. Pelanggan WebSocket

function connect() { var socket = new WebSocket('ws://localhost:8080/greeting'); ws = Stomp.over(socket); ws.connect({}, function(frame) { ws.subscribe("/user/queue/errors", function(message) { alert("Error " + message.body); }); ws.subscribe("/user/queue/reply", function(message) { alert("Message " + message.body); }); }, function(error) { alert("STOMP error " + error); }); } function disconnect() { if (ws != null) { ws.close(); } setConnected(false); console.log("Disconnected"); }

WebSocket baru dibuat menunjuk ke " / salam " untuk pemetaan di WebSocketConfiguration .

Apabila kami melanggan klien untuk " / user / queue / error " dan " / user / queue / reply " adalah tempat kami menggunakan maklumat yang dinyatakan dari bahagian terakhir.

Seperti yang kita lihat, @SendToUser menunjukkan " antrian / kesalahan " tetapi pesan akan dikirim ke " / pengguna / antrian / kesalahan ".

6. Kesimpulannya

Dalam artikel ini, kami telah meneroka cara untuk menghantar mesej terus kepada pengguna atau id sesi dengan Spring WebSocket

Seperti biasa, kod sumber penuh contoh terdapat di GitHub.