二刷 蒼穹外賣day10(含bug修改)

Spring Task

Spring框架提供的任務調度工具,可以按照約定的時間自動執行某個代碼邏輯

cron表達式

一個字符串,通過cron表達式可以定義任務觸發的時間
**構成規則:**分為6或7個域,由空格分隔開,每個域代表一個含義

每個域的含義分別為:秒、分鐘、小時、日、月、周、年(可選)
cron表達式在線生成器:https://cron.qqe2.com/
可以直接在這個網站上面,只要根據自己的要求去生成corn表達式即可。所以一般就不用自己去編寫這個表達式。
通配符:

* 表示所有值;? 表示未說明的值,即不關心它為何值;- 表示一個指定的范圍;, 表示附加一個可能值;/ 符號前表示開始時間,符號后表示每次遞增的值;
**cron表達式案例:***/5 * * * * ? 每隔5秒執行一次0 */1 * * * ? 每隔1分鐘執行一次0 0 5-15 * * ? 每天5-15點整點觸發0 0/3 * * * ? 每三分鐘觸發一次0 0-5 14 * * ? 在每天下午2點到下午2:05期間的每1分鐘觸發0 0/5 14 * * ? 在每天下午2點到下午2:55期間的每5分鐘觸發0 0/5 14,18 * * ? 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發0 0/30 9-17 * * ? 朝九晚五工作時間內每半小時0 0 10,14,16 * * ? 每天上午10點,下午2點,4點
	/*** 處理支付超時訂單*/@Scheduled(cron = "0 * * * * ?")public void processTimeoutOrder(){log.info("處理支付超時訂單:{}", new Date());LocalDateTime time = LocalDateTime.now().plusMinutes(-15);// select * from orders where status = 1 and order_time < 當前時間-15分鐘List<Orders> ordersList = orderMapper.getByStatusAndOrdertimeLT(Orders.PENDING_PAYMENT, time);if(ordersList != null && ordersList.size() > 0){ordersList.forEach(order -> {order.setStatus(Orders.CANCELLED);order.setCancelReason("支付超時,自動取消");order.setCancelTime(LocalDateTime.now());orderMapper.update(order);});}}

每分鐘觸發,每次觸發會查詢狀態為1,即非付款且未付款時間大于15分鐘的訂單,拿到這些訂單后將狀態修改,更新到數據庫中

	/*** 處理“派送中”狀態的訂單*/@Scheduled(cron = "0 0 1 * * ?")public void processDeliveryOrder(){log.info("處理派送中訂單:{}", new Date());// select * from orders where status = 4 and order_time < 當前時間-1小時LocalDateTime time = LocalDateTime.now().plusMinutes(-60);List<Orders> ordersList = orderMapper.getByStatusAndOrdertimeLT(Orders.DELIVERY_IN_PROGRESS, time);if(ordersList != null && ordersList.size() > 0){ordersList.forEach(order -> {order.setStatus(Orders.COMPLETED);orderMapper.update(order);});}}

每天早上一點觸發,將時間超過一個小時的訂單進行修改

WebSocker

基于TCP的網絡協議,實現了瀏覽器與服務器全雙工通信,瀏覽器和服務器只需要一次握手,就可以創建持久性的連接,并進行雙向數據傳輸。
與HTTP協議的對比:
HTTP是短連接,WebSocket是長連接
HTTP通信是單向,基于請求響應模式
WebSocket支持雙向通信
HTTP和WebSocket底層都是TCP連接
![[Pasted image 20250701094005.png]]

WebSokcet缺點:
長期維護長連接有成本
各個瀏覽器支持程度不一
WebSocket是長連接,受網絡限制比較大,需要處理好重連

WebSocket應用場景
1.視頻彈幕
2.網頁聊天
3.體育實況更新
4.股票基金報價實時更新

@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {//存放會話對象private static Map<String, Session> sessionMap = new HashMap();/*** 連接建立成功調用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客戶端:" + sid + "建立連接");sessionMap.put(sid, session);}/*** 收到客戶端消息后調用的方法** @param message 客戶端發送過來的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到來自客戶端:" + sid + "的信息:" + message);}/*** 連接關閉調用的方法** @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("連接斷開:" + sid);sessionMap.remove(sid);}/*** 群發** @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服務器向客戶端發送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}

連接建立成功后存放會話對象:
sessionMap.put(sid,session);

連接關閉后調用:
sessionMap.remove(sid);

服務端給客戶端發送信息:
session.getBasicRemote().sendText(messge);

“@ServerEndpoint” 表明該注解所標注的類是一個 WebSocket 服務器端點,它定義了 WebSocket 服務端與客戶端進行通信的端點。“/ws/{sid}” 是這個 WebSocket 端點的路徑,其中 “{sid}” 是一個占位符,代表會話標識符之類的動態參數,在實際使用中,這個參數值會被具體的內容替換,比如在客戶端連接時傳遞一個具體的會話 ID,服務端就能根據這個路徑和參數來處理不同的 WebSocket 連接請求。 例如,客戶端可能通過 “ws://[localhost:8080/ws/12345](https://localhost:8080/ws/12345)” 這樣的地址連接到這個 WebSocket 端點,其中 “12345” 就是替換 “{sid}” 的具體值。

和@RequestMapping的區別:

應用場景有別

  • WebSocket 服務端端點注解(@ServerEndpoint:主要用于創建基于 WebSocket 協議的通信通道。這種通信是全雙工的,意味著客戶端和服務端能夠同時進行數據傳輸,比較適合需要實時通信的場景,像在線聊天、實時數據推送等。
  • Spring MVC 中處理 HTTP 請求的注解(@RequestMapping:用于構建 RESTful API,遵循的是 HTTP 請求 - 響應模式。客戶端發送請求后,服務端進行處理并返回響應,之后連接就會關閉,主要適用于傳統的 Web 應用場景。

通信模式不同

  • WebSocket 服務端端點注解(@ServerEndpoint:建立的是持久連接,在連接建立之后,客戶端和服務端可以隨時發送消息,無需重新建立連接。
  • Spring MVC 中處理 HTTP 請求的注解(@RequestMapping:采用的是無狀態的請求 - 響應模式,每次請求都需要重新建立連接。

注解參數不一樣

  • WebSocket 服務端端點注解(@ServerEndpoint:可以設置路徑參數(如 /{sid})、子協議以及編碼器 / 解碼器等。
  • Spring MVC 中處理 HTTP 請求的注解(@RequestMapping:能夠指定 HTTP 方法(GET、POST 等)、請求頭、請求參數以及 consumes/produces 等內容。

方法簽名有差異

  • WebSocket 服務端端點注解(@ServerEndpoint:端點方法要處理生命周期事件,例如 onOpenonMessageonClose 等。
  • Spring MVC 中處理 HTTP 請求的注解(@RequestMapping:方法的返回值會直接轉換為 HTTP 響應,像 JSON、XML 等格式。

來單提醒

用戶下單并支付成功后,需要第一時間同時外賣商家
通過WebSocket實現管理端頁面和服務端保持長連接
客戶支付后,調用WebSocket實現服務端向客戶端推送消息
客戶端瀏覽器解析服務器推送的消息,判斷是來單提醒還是催單,進行對應的消息提示和語音播報
由于我并沒有實現支付功能,所以原代碼中的來單提醒在paySuccess中是無法調用的,我將其移動到了payment函數之中,并在Mapper中定義了一個新的查詢函數

@Select("select * from orders where number=#{id} ")  
Orders getByOrderId(Long id);

service

  
@Override  
public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {  Long userId = BaseContext.getCurrentId();  userMapper.getById(userId);  JSONObject jsonObject = new JSONObject();  jsonObject.put("code", "ORDERPAID");  OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);  vo.setPackageStr(jsonObject.getString("package"));  Map map = new HashMap();  Long orderNumber= Long.valueOf(ordersPaymentDTO.getOrderNumber());  Orders byOrderId = orderMapper.getByOrderId(orderNumber);  //#########map.put("type", 1);//消息類型,1表示來單提醒  map.put("orderId", byOrderId.getId());  map.put("content", "訂單號:" + orderNumber.toString());  //通過WebSocket實現來單提醒,向客戶端瀏覽器推送消息  webSocketServer.sendToAllClient(JSON.toJSONString(map));  //#########return vo;  }

收到推送
![[Pasted image 20250701143111.png]]

bug修改

起因是在寫代碼的時候發現一直報服務器錯誤
![[Pasted image 20250701141324.png]]

我以為是我代碼的問題,死活改不對。。。。
后面一看瀏覽器提示404,我就知道應該是前端發送的請求地址有問題,
找到這個文件,在里面搜索ws://localhost
![[Pasted image 20250701142638.png]]![[Pasted image 20250701142721.png]]

這里我的后端端口是8080,我就填的8080,具體看個人的后端端口
修改好之后重啟nginx和java后端,刷新之后顯示連接上了
![[Pasted image 20250701142823.png]]

總結

1. Spring Task

Spring框架提供的任務調度工具,可以按約定的時間自動執行某個代碼邏輯
cron表達式 分為6或7個域,由空格分隔開
每個域含義分別為秒、分、時、日、月、周
通配符

2.WebSocker

基于TCP的網絡協議,實現了全雙工通信,更消耗資源,對網絡要求高,適合頻繁的資源傳輸
使用場景:
彈幕、實時聊天、實況更新、股票更新

3.@ServerEndPoint與@RequestMapping的區別

應用場景不同:@ServerEndPoint主要創建基于WebSocke協議,@RequestMapping遵循HTTP請求,客戶端發送,服務器響應后關閉連接
通信模式不同:webSocket服務端端點注解建立的是持久連接,而HTTP請求采用的是無狀態的請求-響應模式,每次請求都需要重新建立
注解參數不同:Websocket設置參數路徑(/{sid})- `{sid}`是路徑參數占位符,用于標識不同的客戶端會話(如用戶 ID)。在服務端方法中,通過`@PathParam("sid")`注解獲取該參數
方法簽名不同:WebSocket端點方法要處理生命周期事件,例如 `onOpen`、`onMessage`、`onClose` 等。@RequestMapping的返回值會轉換為HTTP響應

4.WebSocket 服務端如何實現向所有客戶端群發消息?

回答:
通過維護一個會話集合(如Map<String, Session>),遍歷所有會話并調用sendText()方法:

public void sendToAllClient(String message) {for (Session session : sessionMap.values()) {session.getBasicRemote().sendText(message);}
}

其中sessionMap存儲客戶端 ID 與會話的映射,確保群發時能訪問所有活躍連接。

5.WebSocket 連接時出現 404 錯誤,可能的原因有哪些?

  1. 服務端路徑配置錯誤:如@ServerEndpoint的路徑與客戶端請求的 URL 不匹配(例:服務端為/ws/{sid},客戶端請求/websocket/123)。
  2. 端口不匹配:客戶端連接的端口(如ws://localhost:8080)與服務端實際端口不一致。
  3. 未正確部署 WebSocket 服務:如未添加@Component注解或未配置 WebSocket 容器。

WebSocket 的onOpenonMessageonClose方法的觸發時機是什么?

  • onOpen:當客戶端與服務端成功建立 WebSocket 連接時觸發。
  • onMessage:當服務端接收到客戶端發送的消息時觸發。
  • onClose:當連接關閉(客戶端斷開、服務端主動關閉或異常斷開)時觸發。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87217.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87217.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87217.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android Native 之 inputflinger進程分析

Android IMS原理解析 - 簡書 Android 輸入事件分發全流程梳理&#xff08;一&#xff09;_android input事件分發流程-CSDN博客 Android 輸入事件分發全流程梳理&#xff08;二&#xff09;_android輸入事件流程圖-CSDN博客 inputflinger模塊與surfaceflinger模塊在同級目錄…

Python實例題:基于 Flask 的在線聊天系統

目錄 Python實例題 題目 要求&#xff1a; 解題思路&#xff1a; 代碼實現&#xff1a; Python實例題 題目 基于 Flask 的在線聊天系統 要求&#xff1a; 使用 Flask 框架構建一個實時在線聊天系統&#xff0c;支持以下功能&#xff1a; 用戶注冊、登錄和個人資料管理…

v-bind指令

好的&#xff0c;我們來學習 v-bind 指令。這個指令是理解 Vue 數據驅動思想的基石。 核心功能&#xff1a;v-bind 的作用是將一個或多個 HTML 元素的 attribute (屬性) 或一個組件的 prop (屬性) 動態地綁定到 Vue 實例的數據上。 簡單來說&#xff0c;它在你的數據和 HTML …

【設計模式04】單例模式

前言 整個系統中只會出現要給實例&#xff0c;比如Spring中的Bean基本都是單例的 UML類圖 無 代碼示例 package com.sw.learn.pattern.B_create.c_singleton;public class Main {public static void main(String[] args) {// double check locking 線程安全懶加載 ?? //…

飛算科技依托 JavaAI 核心技術,打造企業級智能開發全場景方案

在數字經濟蓬勃發展的當下&#xff0c;企業對智能化開發的需求愈發迫切。飛算數智科技&#xff08;深圳&#xff09;有限公司&#xff08;簡稱 “飛算科技”&#xff09;作為自主創新型數字科技公司與國家級高新技術企業&#xff0c;憑借深厚的技術積累與創新能力&#xff0c;以…

20250701【二叉樹公共祖先】|Leetcodehot100之236【pass】今天計劃

20250701 思路與錯誤記錄1.二叉樹的數據結構與初始化1.1數據結構1.2 初始化 2.解題 完整代碼今天做了什么 題目 思路與錯誤記錄 1.二叉樹的數據結構與初始化 1.1數據結構 1.2 初始化 根據列表&#xff0c;順序存儲構建二叉樹 def build_tree(nodes, index0):# idx是root開始…

Web應用開發 --- Tips

Web應用開發 --- Tips General后端需要做參數校驗代碼風格和Api設計風格的一致性大于正確性數據入庫時間應由后端記錄在對Api修改的時候&#xff0c;要注意兼容情況&#xff0c;避免breaking change 索引對于查詢字段&#xff0c;注意加索引對于唯一的字段&#xff0c;考慮加唯…

CSS 安裝使用教程

一、CSS 簡介 CSS&#xff08;Cascading Style Sheets&#xff0c;層疊樣式表&#xff09;是用于為 HTML 頁面添加樣式的語言。通過 CSS 可以控制網頁元素的顏色、布局、字體、動畫等&#xff0c;是前端開發的三大核心技術之一&#xff08;HTML、CSS、JavaScript&#xff09;。…

機器學習中為什么要用混合精度訓練

目錄 FP16與顯存占用關系機器學習中一般使用混合精度訓練&#xff1a;FP16計算 FP32存儲關鍵變量。 FP16與顯存占用關系 顯存&#xff08;Video RAM&#xff0c;簡稱 VRAM&#xff09;是顯卡&#xff08;GPU&#xff09;專用的內存。 FP32&#xff08;單精度浮點&#xff09;&…

[附源碼+數據庫+畢業論文+答辯PPT]基于Spring+MyBatis+MySQL+Maven+vue實現的中小型企業財務管理系統,推薦!

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本中小型企業財務管理就是在這樣的大環境下誕生&#xff0c;其可以幫助管理者在短時間內處理完畢龐大的數據信…

華為云Flexus+DeepSeek征文 | 對接華為云ModelArts Studio大模型:AI賦能投資理財分析與決策

引言&#xff1a;AI金融&#xff0c;開啟智能投資新時代?? 隨著人工智能技術的飛速發展&#xff0c;金融投資行業正迎來前所未有的變革。??華為云ModelArts Studio??結合??Flexus高性能計算??與??DeepSeek大模型??&#xff0c;為投資者提供更精準、更高效的投資…

從模型部署到AI平臺:云原生環境下的大模型平臺化演進路徑

&#x1f4dd;個人主頁&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的關注 &#x1f339;&#x1f339; 一、引言&#xff1a;部署只是起點&#xff0c;平臺才是終局 在過去一年&#xff0c;大語言模型的飛速發展推動了AI生產力浪潮。越來越多…

UI前端大數據可視化創新:利用AR/VR技術提升用戶沉浸感

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩! 在大數據與沉浸式技術高速發展的今天&#xff0c;傳統二維數據可視化已難以滿足復雜數據場景的…

MacOS 安裝brew 國內源【超簡潔步驟】

?/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"請輸入序號&#xff1a;1

GENESIS64:全球知名的工業設備監控與可視化平臺

一、概述 GENESIS64是一款由ICONICS開發的先進工業自動化軟件平臺&#xff0c;專為實現實時數據可視化、智能化監控及管理而設計。該平臺采用模塊化架構&#xff0c;具有高效的數據處理能力和靈活的擴展性&#xff0c;適用于各類工業環境&#xff0c;幫助企業實現自動化運營&a…

RNN(Recurrent Neural Network,循環神經網絡)家族詳解(RNN,LSTM,GRU)

文章目錄 一、RNN基礎&#xff1a;序列建模的核心思想1.1 RNN的本質與核心機制1.2 應用場景與結構分類 二、傳統RNN&#xff1a;序列模型的起點2.1 內部結構與數學表達2.2 計算示例2.3 RNN在Pytorch中的API2.4 代碼示例2.5 優缺點與梯度問題 三、LSTM&#xff1a;門控機制破解長…

多云密鑰統一管理實戰:CKMS對接阿里云/華為云密鑰服務

某保險公司因阿里云KMS密鑰與華為云密鑰割裂管理&#xff0c;導致勒索事件中解密失敗&#xff01;據統計&#xff0c;73%企業因多云密鑰分散管理引發數據恢復延遲&#xff08;IDC 2024&#xff09;。本文將詳解安當CKMS統一納管方案&#xff0c;實現跨云密鑰全生命周期管控&…

光伏接入承載力計算仿真:基于圖計算技術的自動建模技術研究

光伏接入承載力計算仿真:基于圖計算技術的自動建模技術研究 一、 引言:挑戰與機遇 光伏發電的大規模接入對中低壓配電網的安全穩定運行帶來了巨大挑戰。精確評估電網對光伏的承載力(Hosting Capacity, HC)是保障消納與安全的關鍵。傳統承載力評估嚴重依賴電網仿真,而仿真…

如何在Excel中每隔幾行取一行

如何在Excel中每隔幾行取一行 摘要&#xff1a; Excel中快速實現每隔n行取一行的技巧&#xff1a;使用OFFSET函數配合ROW函數即可實現。公式為OFFSET(起始單元格,(ROW(A1)-1)*n,)&#xff0c;其中n為間隔行數。例如從A2開始每2行取一行&#xff0c;公式為OFFSET(A2,(ROW(A1)-1)…

【MariaDB】MariaDB Server 11.3.0 Alpha下載、安裝、配置

MariaDB是一個開源關系型數據庫管理系統&#xff08;RDBMS&#xff09;&#xff0c;由MySQL的原始開發者Michael Widenius主導開發。作為MySQL的分支&#xff0c;MariaDB旨在保持與MySQL的高度兼容性&#xff0c;同時提供性能優化、新功能和更好的開源承諾。 目錄 MariaDB下載 …