SpringBoot實時推送的三個經(jīng)典案例
在現(xiàn)代Web應用中,實時消息推送已經(jīng)成為一項關鍵功能。它不僅能夠提升用戶體驗,還能在諸如聊天應用、實時通知系統(tǒng)等領域發(fā)揮重要作用。Spring Boot作為一個流行的后端框架,提供了多種實現(xiàn)實時消息推送的方法。本文將詳細介紹三個經(jīng)典案例,分別是使用長輪詢(Long Polling)、WebSocket和GraphQL實現(xiàn)實時消息推送。
案例一:長輪詢(Long Polling)
長輪詢是對傳統(tǒng)短輪詢的一種改進,通過減少無效請求來降低服務器壓力。在短輪詢中,客戶端會定期向服務器發(fā)送請求以檢查是否有新的消息。這種方式會頻繁占用服務器資源,特別是在消息不頻繁更新的情況下。
長輪詢則通過保持一個打開的連接直到有新消息到達來改進這一點??蛻舳税l(fā)起一個請求,服務器會延遲響應,直到有新數(shù)據(jù)或連接超時。在Spring Boot中,可以使用DeferredResult來實現(xiàn)長輪詢。
實現(xiàn)步驟:
創(chuàng)建控制器:定義一個控制器來處理長輪詢請求和消息發(fā)布。
@Controller
@RequestMapping(“/polling”)
public class PollingController {
// 存放監(jiān)聽某個Id的長輪詢集合
public static Multimap<String, DeferredResult> watchRequests = Multimaps.synchronizedMultimap(HashMultimap.create());
@GetMapping(path = "watch/{id}")
@ResponseBody
public DeferredResult<String> watch(@PathVariable String id) {
DeferredResult<String> deferredResult = new DeferredResult<>(TIME_OUT);
deferredResult.onCompletion(() -> watchRequests.remove(id, deferredResult));
watchRequests.put(id, deferredResult);
return deferredResult;
}
@GetMapping(path = "publish/{id}")
@ResponseBody
public String publish(@PathVariable String id) {
if (watchRequests.containsKey(id)) {
Collection<DeferredResult<String>> deferredResults = watchRequests.get(id);
for (DeferredResult<String> deferredResult : deferredResults) {
deferredResult.setResult("我更新了" + new Date());
}
}
return "Published";
}
}前端處理:前端需要處理長輪詢請求和響應,當收到非超時響應時,更新頁面數(shù)據(jù)并重新發(fā)起長輪詢請求。
長輪詢的優(yōu)勢在于相對實時且減少了服務器資源的浪費,但依然存在較多請求的問題。
案例二:WebSocket
WebSocket提供了一種在單個TCP連接上進行全雙工通信的方法。它使得客戶端和服務器之間的數(shù)據(jù)交換變得更加簡單和高效。
實現(xiàn)步驟:
配置WebSocket:在Spring Boot中配置WebSocket處理器。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebSocketHandler(), “/ws”).setAllowedOrigins(“*”);
}
}創(chuàng)建WebSocket處理器:處理WebSocket連接和消息。
public class WebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
session.sendMessage(new TextMessage("Hello, " + payload + “!”));
}
}前端處理:前端使用JavaScript創(chuàng)建WebSocket連接,并處理消息的接收和發(fā)送。
WebSocket的優(yōu)勢在于能夠?qū)崟r、雙向通信,非常適合需要頻繁更新的場景,如實時聊天應用。
案例三:GraphQL訂閱
GraphQL是一種用于API的查詢語言,它允許客戶端精確地請求所需的數(shù)據(jù)。GraphQL的訂閱功能使得它也能夠用于實時數(shù)據(jù)推送。
實現(xiàn)步驟:
集成GraphQL:在Spring Boot項目中集成GraphQL庫。
在pom.xml中添加GraphQL依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
<version>2.7.9</version>
</dependency>定義GraphQL Schema:包括類型定義、查詢和訂閱操作。
定義消息類型
type Message {
id: ID!
content: String!
}定義訂閱
type Subscription {
newMessage: Message
}實現(xiàn)Resolver:處理GraphQL查詢和訂閱請求。
@Component
public class GraphQLSubscriptionResolver {
private Publisher messagePublisher = Flux.create(emitter -> {
// 模擬消息發(fā)布
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(() -> {
Message message = new Message();
message.setId(UUID.randomUUID().toString());
message.setContent("New message at " + new Date());
emitter.next(message);
}, 0, 5, TimeUnit.SECONDS);
});
@SubscriptionMapping
public Publisher<Message> newMessage() {
return messagePublisher;
}}前端處理:前端使用GraphQL客戶端訂閱新消息,并處理接收到的數(shù)據(jù)。
GraphQL訂閱的優(yōu)勢在于能夠精確請求所需數(shù)據(jù),并且能夠在數(shù)據(jù)變化時實時推送更新。
總結(jié)
本文介紹了三種使用Spring Boot實現(xiàn)實時消息推送的方法:長輪詢、WebSocket和GraphQL訂閱。每種方法都有其獨特的優(yōu)勢和適用場景。長輪詢適用于對實時性要求不是特別高,但需要減少服務器資源浪費的場景;WebSocket適用于需要頻繁雙向通信的場景;GraphQL訂閱則適用于需要精確請求數(shù)據(jù)并實時更新的場景。根據(jù)具體需求選擇合適的方法,可以實現(xiàn)高效、實時的消息推送功能。
到此這篇關于SpringBoot實時推送的三個經(jīng)典案例的文章就介紹到這了,更多相關SpringBoot實時推送內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
springMVC使用ajaxFailUpload上傳圖片的方法
這篇文章主要介紹了springMVC使用ajaxFailUpload上傳圖片的相關知識,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06
深度解析Java常量池中的Integer緩沖池和String常量池
為了減少對象重復創(chuàng)建、提升運行時效率,Java 內(nèi)部提供了兩種重要的優(yōu)化機制Integer 緩沖池(IntegerCache)和 String 常量池(String Pool),本文將深入剖析兩大常量池的底層實現(xiàn)、工作流程、適用范圍,并通過流程圖和代碼示例幫助你徹底掌握2026-05-05
spring boot 配置freemarker及如何使用freemarker渲染頁面
springboot中自帶的頁面渲染工具為thymeleaf 還有freemarker這兩種模板引擎,本文重點給大家介紹spring boot 配置freemarker及如何使用freemarker渲染頁面,感興趣的朋友一起看看吧2023-10-10
MyBatisPlus PaginationInterceptor分頁插件的使用詳解
這篇文章主要介紹了MyBatisPlus PaginationInterceptor分頁插件的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03

