自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

基于Spring Boot,一步步教你用Websockets和STOMP進(jìn)行消息推送

開發(fā) 前端
在本文中,我們學(xué)習(xí)了如何使用Spring Boot應(yīng)用程序、WebSockets和STOMP協(xié)議發(fā)送推送通知。如果希望使用外部的ActiveMQ實例,只需將其連接到應(yīng)用程序,因為ActiveMQ也支持STOMP協(xié)議。

1 引言

推送通知是一種實時消息傳遞形式,通過它網(wǎng)站可以向用戶實時通知特定事件。通常使用WebSockets實現(xiàn)推送通知,這種技術(shù)提供了客戶端和服務(wù)器之間的雙向通信,從而實現(xiàn)了實時消息的處理。

本文使用WebSockets來實現(xiàn)推送通知,并使用STOMP協(xié)議在客戶端和服務(wù)器之間進(jìn)行通信。

2 什么是STOMP

STOMP代表簡單文本導(dǎo)向的消息協(xié)議(Simple Text Oriented Messaging Protocol)。由于WebSockets是一種低級協(xié)議,使用幀(frames)來傳輸數(shù)據(jù),而STOMP是一種高級協(xié)議,定義了如何解釋某些幀類型中的數(shù)據(jù)。這些幀類型包括CONNECT、SEND、ACK等。因此,使用STOMP能夠更加簡化使用WebSockets進(jìn)行數(shù)據(jù)的發(fā)送、接收和解析過程。

有了這個基礎(chǔ),接下來創(chuàng)建服務(wù)器應(yīng)用程序。

3 創(chuàng)建一個應(yīng)用程序

到https://start.spring.io創(chuàng)建一個Spring Boot應(yīng)用程序,并添加以下依賴項:

Spring Boot Starter Websockets

現(xiàn)在,使用一個嵌入式消息代理,它將是一個提供WebSocket功能的內(nèi)存中代理。給代理添加一些目的地。這些目的地指的是將要發(fā)送消息的路徑。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/all","/specific");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
         registry.addEndpoint("/ws");
         registry.addEndpoint("/ws").withSockJS();
    }
}

在第一部分中,啟用了一個帶有兩個目的地(/all和/specific)的代理。/all目的地將用于向所有用戶發(fā)送通知,/specific目的地用于向特定用戶發(fā)送通知。

接下來,設(shè)置應(yīng)用程序的目的地,即 /app,這樣就可以向應(yīng)用程序發(fā)送信息了。

在第二部分中,注冊了STOMP端點。其中一個啟用了SockJS,另一個僅使用WebSocket。之所以這樣做,是因為并非所有瀏覽器都支持WebSocket,當(dāng)不可用時,可以回退到使用SockJS。

4 向所有用戶發(fā)送推送通知

先看一下第一個用例,即向所有用戶發(fā)送推送通知。

為此,首先實現(xiàn)一個控制器,該控制器會把來自一個客戶端的信息轉(zhuǎn)發(fā)給所有客戶端。

@org.springframework.stereotype.Controller
public class Controller {

    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/application")
    @SendTo("/all/messages")
    public Message send(final Message message) throws Exception {
        return message;
    }
}

在上面的代碼中,我們接受/application端點上的消息。這實際上是之前定義的應(yīng)用程序目的地/app的子目的地。這意味著客戶端必須把消息發(fā)送到/app/application目的地才能到達(dá)該處理程序。

接下來,把傳入的消息轉(zhuǎn)發(fā)到/all/messages?,F(xiàn)在,訂閱該目的地的所有客戶端都將收到發(fā)送給所有客戶端的消息。

來看看HTML頁面上的客戶端代碼:

<script type="text/javascript">
        var stompClient = null;

        var socket = new SockJS('/ws');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            console.log(frame);
            stompClient.subscribe('/all/messages', function(result) {
                show(JSON.parse(result.body));
            });
        });

在這里,使用一個STOMP客戶端,在WebSocket上建立連接,然后訂閱/all/messages上的消息。

現(xiàn)在,為了將消息發(fā)送給應(yīng)用程序,有以下的JavaScript函數(shù),它將消息發(fā)送到/app/application:

function sendMessage() {
    var text = document.getElementById('text').value;
    stompClient.send("/app/application", {},
      JSON.stringify({'from':from, 'text':text}));
}

它簡單地從文本字段中獲取文本值,并將其發(fā)送到代理的應(yīng)用程序目標(biāo)。

這是通過下面顯示的一個簡單表單進(jìn)行連接的。

圖片圖片

為了測試這個,我們向所有連接的客戶端發(fā)送一個推送通知"Notification to all"。

圖片圖片

這里有兩個連接的客戶端,兩個客戶端都立即收到了通知。

現(xiàn)在,在這里只是顯示了從WebSocket接收到的內(nèi)容,但可以根據(jù)需要使用CSS和JavaScript來自定義通知彈出窗口或通知標(biāo)簽。

這就是如何向所有用戶發(fā)送通知。那么如何向特定用戶發(fā)送通知呢?

5 向特定用戶發(fā)送推送通知

要向特定用戶發(fā)送通知,我們需要收件人的用戶ID。這意味著接收方用戶需要登錄并提供一個有效的會話來標(biāo)識用戶的用戶ID。

為此,我們將集成Spring Security。因此,添加以下依賴項。

Spring Boot Starter Security

添加了Spring Security依賴項后,我們需要定義一個安全配置來允許使用WebSockets進(jìn)行連接。

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .authorizeHttpRequests()
                .mvcMatchers("/","/ws/**")
                .permitAll()
            .and()
            .authorizeHttpRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .logout( logout -> logout.logoutSuccessUrl("/"));
    return http.build();
}

@Bean
public InMemoryUserDetailsManager userDetailsService() {
    UserDetails user = User.withDefaultPasswordEncoder()
            .username("test")
            .password("test")
            .roles("USER")
            .build();

    return new InMemoryUserDetailsManager(user);
}

在這里,我們允許所有連接到/ws路徑的連接,以便在沒有任何身份驗證的情況下進(jìn)行WebSocket通信,還定義了一個名為"test"的靜態(tài)用戶。

還記得在上面的消息代理設(shè)置中創(chuàng)建的/specific目標(biāo)嗎?現(xiàn)在將使用它來發(fā)送特定的消息。

首先,在控制器中添加一個處理程序,用于接收消息并將其發(fā)送給特定的用戶,這些用戶將使用它們的用戶名進(jìn)行標(biāo)識。

@org.springframework.stereotype.Controller
public class Controller {

    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/application")
    @SendTo("/all/messages")
    public Message send(final Message message) throws Exception {
        return message;
    }

    @MessageMapping("/private")
    public void sendToSpecificUser(@Payload Message message) {
        simpMessagingTemplate.convertAndSendToUser(message.getTo(), "/specific", message);
    }
}

現(xiàn)在,在sendToSpecificUser方法中,我們接受使用/app/private發(fā)送的消息。消息包含要發(fā)送給接收者的文本以及接收者的用戶ID。

消息模板所做的是將消息發(fā)送到以/user開頭的目標(biāo),然后將其附加到我們在convertAndSendToUser函數(shù)調(diào)用中指定的目標(biāo),即/specific,然后附加所指定的用戶的用戶會話ID。

因此,convertAndSendToUser將消息發(fā)送到目標(biāo)/user/specific-<user-session-id>。這個目標(biāo)是在用戶登錄并訂閱/user/specific時創(chuàng)建的。

當(dāng)用戶登錄并訂閱/user/specific時,它會發(fā)送有效的已登錄會話ID。然后,Spring自動處理訂閱/user/specific將自動訂閱已登錄用戶的特定目標(biāo),即/user/specific-<user-session-id>。

這也意味著只有用戶登錄時才能發(fā)送通知。

現(xiàn)在,添加一個新的文本塊并訂閱用戶特定的目標(biāo)。

socket = new SockJS('/ws');
privateStompClient = Stomp.over(socket);
privateStompClient.connect({}, function(frame) {
        console.log(frame);
        privateStompClient.subscribe('/user/specific', function(result) {
        console.log(result.body)
            show(JSON.parse(result.body));
        });
    });

圖片圖片

打開兩個客戶端,并使用"test"用戶登錄第二個客戶端??梢允褂?login端點觸發(fā)登錄。

在上面的圖像中,正在以"test"用戶登錄第二個客戶端。

登錄后,首先向所有客戶端發(fā)送消息。

圖片圖片

所以,即使已登錄的用戶也會收到發(fā)送給所有客戶端的通知。

現(xiàn)在,向"test"用戶發(fā)送一個私有通知。

圖片圖片

在上面的圖像中,我們?yōu)樘囟ㄓ脩籼峁┝艘粭l消息,并指定了特定用戶的用戶ID,即"test",通知只會傳遞給已登錄的用戶。

這是一個關(guān)于它是如何工作的簡短演示。

圖片圖片

6 結(jié)語

在本文中,我們學(xué)習(xí)了如何使用Spring Boot應(yīng)用程序、WebSockets和STOMP協(xié)議發(fā)送推送通知。如果希望使用外部的ActiveMQ實例,只需將其連接到應(yīng)用程序,因為ActiveMQ也支持STOMP協(xié)議。這樣,我們就可以通過應(yīng)用程序?qū)⑾⒅欣^到外部的ActiveMQ實例,實現(xiàn)更靈活和可定制的消息傳遞。通過這種方式,可以輕松地實現(xiàn)推送通知功能,為用戶提供實時的信息更新和交互體驗。希望這篇文章對讀者有所幫助!

責(zé)任編輯:武曉燕 來源: Java學(xué)研大本營
相關(guān)推薦

2011-09-05 12:36:08

路由器限速linux路由器

2017-12-25 11:50:57

LinuxArch Linux

2018-06-11 15:30:12

2017-01-19 21:08:33

iOS路由構(gòu)建

2019-03-05 14:09:27

Docker存儲容器

2019-07-09 15:23:22

Docker存儲驅(qū)動

2010-08-10 11:31:36

路由器配置NAT

2009-04-15 09:29:07

2018-12-24 10:04:06

Docker存儲驅(qū)動

2025-02-25 09:41:27

2010-08-12 10:02:16

路由器NAT

2009-08-14 11:35:01

Scala Actor

2010-03-04 16:28:17

Android核心代碼

2010-04-07 13:05:57

2024-11-18 17:12:18

C#編程.NET

2016-11-02 18:54:01

javascript

2011-05-10 10:28:55

2009-12-18 16:35:56

如何查找局域網(wǎng)發(fā)生的故

2024-08-30 08:30:29

CPU操作系統(tǒng)寄存器

2024-09-30 09:56:59

點贊
收藏

51CTO技術(shù)棧公眾號