蒼穹外賣--WebSocket、來單提醒、客戶催單

WebSocket

1.介紹

WebSocket是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工通信——瀏覽器和服務器只需要一次握手,兩者之間就可以創建持久性的連接,并進行雙向數據傳送。

HTTP協議和WebSocket協議對比:

①Http是短連接

②WebSocket是長連接

③Http通信是單向的,基于請求響應模式

④WebSocket支持雙向通信

⑤Http和WebSocket底層都是TCP連接

應用場景:

①視頻彈幕

②網頁聊天

③體育實況更新

④股票基金報價實時更新

效果展示:

2.入門案例

實現步驟:

①直接使用websocket.html頁面作為WebSocket客戶端

<!DOCTYPE HTML>
<html>
<head><meta charset="UTF-8"><title>WebSocket Demo</title>
</head>
<body><input id="text" type="text" /><button onclick="send()">發送消息</button><button onclick="closeWebSocket()">關閉連接</button><div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;var clientId = Math.random().toString(36).substr(2);//判斷當前瀏覽器是否支持WebSocketif('WebSocket' in window){//連接WebSocket節點websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);}else{alert('Not support websocket')}//連接發生錯誤的回調方法websocket.onerror = function(){setMessageInnerHTML("error");};//連接成功建立的回調方法websocket.onopen = function(){setMessageInnerHTML("連接成功");}//接收到消息的回調方法websocket.onmessage = function(event){setMessageInnerHTML(event.data);}//連接關閉的回調方法websocket.onclose = function(){setMessageInnerHTML("close");}//監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。window.onbeforeunload = function(){websocket.close();}//將消息顯示在網頁上function setMessageInnerHTML(innerHTML){document.getElementById('message').innerHTML += innerHTML + '<br/>';}//發送消息function send(){var message = document.getElementById('text').value;websocket.send(message);}//關閉連接function closeWebSocket() {websocket.close();}
</script>
</html>

②導入WebSocket的Maven坐標

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

③導入WebSocket服務端組件WebSocketServer,用于和客戶端通信

package com.sky.websocket;import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;/*** WebSocket服務*/
@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();}}}}

④導入配置類WebSocketConfiguration,注冊WebSocket的服務端組件

package com.sky.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置類,用于注冊WebSocket的Bean*/
@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

⑤導入定時任務類WebSocketTask,定時向客戶端推送數據

package com.sky.task;import com.sky.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;@Component
public class WebSocketTask {@Autowiredprivate WebSocketServer webSocketServer;/*** 通過WebSocket每隔5秒向客戶端發送消息*/@Scheduled(cron = "0/5 * * * * ?")//這個在后面的代碼里還是注釋掉好一些,不然語音播報會一直播報public void sendMessageToClient() {webSocketServer.sendToAllClient("這是來自服務端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));}
}

來單提醒

1.實現思路

用戶下單并支付成功后,需要第一時間通知外賣商家。通知的形式有如下兩種:

①語音播報

②彈出提示框

設計:

①通過WebSocket實現管理端頁面和服務端保持長連接狀態

②當客戶支付后,調用WebSocket的相關API實現服務端向客戶端推送消息

③客戶端瀏覽器解析服務端推送消息,判斷是來單提醒還催單,進行相應的消息提示和語音播報

④約定服務端發送給客戶端瀏覽器的數據格式為JSON,字段包括:type,orderId,content

? ? ? ? -type為消息類型,1為來單提醒 2為客戶催單

? ? ? ? -orderId為訂單id

? ? ? ? -content為消息內容

2.實現代碼

在OrderServiceImpl.java中的paySucess方法中添加如下代碼:

//通過websocket向客戶端瀏覽器推送消息type orderId contextMap map = new HashMap();map.put("type",1);//1表示來單提醒 2表示客戶催單map.put("orderId",ordersDB.getId());map.put("content","訂單號:"+outTradeNo);String json = JSON.toJSONString(map);webSocketServer.sendToAllClient(json);

客戶催單

1.實現思路

用戶在小程序中點擊催單按鈕后,需要第一時間通知外賣商家。通知的形式有如下兩種:

①語音播報

②彈出提示框

設計:

①通過WebSocket實現管理端頁面和服務端保持長連接狀態

②當客戶支付后,調用WebSocket的相關API實現服務端向客戶端推送消息

③客戶端瀏覽器解析服務端推送消息,判斷是來單提醒還催單,進行相應的消息提示和語音播報

④約定服務端發送給客戶端瀏覽器的數據格式為JSON,字段包括:type,orderId,content

? ? ? ? -type為消息類型,1為來單提醒 2為客戶催單

? ? ? ? -orderId為訂單id

? ? ? ? -content為消息內容

接口設計:

2.實現代碼

OrderController.java代碼:

/*** 客戶催單* @param id* @return*/@GetMapping("/reminder/{id}")@ApiOperation("客戶催單")public Result reminder(@PathVariable("id") Long id){orderService.reminder(id);return Result.success();}

OrderService.java代碼:

/*** 客戶催單* @param id*/void reminder(Long id);

OrderServiceImpl.java代碼:

/*** 客戶催單* @param id*/public void reminder(Long id){// 根據id查詢訂單Orders ordersDB = orderMapper.getById(id);// 校驗訂單是否存在if (ordersDB == null) {throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);}//通過websocket向客戶端瀏覽器推送消息type orderId contextMap map = new HashMap();map.put("type",2);//1表示來單提醒 2表示客戶催單map.put("orderId",id);map.put("content","訂單號:"+ordersDB.getNumber());String json = JSON.toJSONString(map);webSocketServer.sendToAllClient(json);}

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

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

相關文章

Linux 信號(Signal)與信號量(Semaphore)區別

特性信號 (Signal)信號量 (Semaphore)本質軟件中斷進程間同步機制用途通知進程發生了某個事件控制對共享資源的訪問通信方向單向 (內核→進程 或 進程→進程)多進程共享數據類型整數信號編號內核維護的計數器持久性瞬時,不排隊持久,直到顯式釋放實現層次內核實現內核或用戶空…

華為OD機考-觀看文藝匯演問題-區間問題(JAVA 2025B卷)

import java.util.*; /*** version Ver 1.0* date 2025/6/20* description 觀看文藝匯演*/ public class WatchMovie {public static void main(String[] args) {Scanner sc new Scanner(System.in);int num Integer.parseInt(sc.nextLine());List<Movie> movies new …

DeepSeek今天喝什么隨機奶茶推薦器

用DeepSeek生成了一個隨機奶茶推薦器-今天喝什么&#xff0c;效果非常棒&#xff01;UI界面美觀。 提示詞prompt如下 用html5幫我生成一個今天喝什么的網頁 點擊按鈕隨機生成奶茶品牌等&#xff0c;要包括中國常見的知名的奶茶品牌 如果不滿意還可以隨機再次生成 ui界面要好看 …

【國產AI服務器】全國產PCIE5.0交換板,替代博通89104/89144,支持海光、龍芯等平臺

實物圖 核心硬件配置 1、控制器芯片? 采用國產TL63104控制芯片?&#xff0c;支持2.5GT/s、5GT/s、8GT/s、16GT/s、32GT/s的PCIe傳輸速率&#xff0c;支持968Lanes。支持6個x16的group和1個x8的group&#xff0c;每個group支持1至8個端口。x16group支持x16、x8、x4、x2端口…

GPIO-LED驅動

一、LED引腳說明 寄存器地址地圖&#xff1a; 原理圖&#xff1a; 關于MOS管的說明&#xff1a; 總結&#xff1a;當GPIO0_B5這個引腳輸出高電平的時候&#xff0c;對應的N-MOS管導通—LED點亮 當GPIO0_B5這個引腳輸出低電平的時候&#xff0c;對應的N-MOS管截止---LED熄滅 二…

Gartner《Generative AI Use - Case Comparison for Legal Departments》

概述 這篇文章由 Gartner, Inc. 出品,聚焦于生成式人工智能(GenAI)在法律部門中的應用情況,通過對 16 個較為突出的 GenAI 法律技術應用場景進行分析,從商業價值和可行性兩個維度進行評估,旨在為法律總顧問等提供戰略對話依據,以便更好地做出技術投資決策,推動法律部門…

Vue 中 filter 過濾的語法詳解與注意事項

Vue 中 filter 過濾的語法詳解與注意事項 在 Vue.js 中,"過濾"通常指兩種不同概念:模板過濾器(Vue 2 特性)和數組過濾(數據過濾)。由于 Vue 3 已移除模板過濾器,我將重點介紹更實用且通用的數組過濾語法和注意事項。 一、數組過濾核心語法(推薦方式) 1. …

webpack+vite前端構建工具 -6從loader本質看各種語言處理 7webpack處理html

6 從loader本質看各種語言處理 語法糖&#xff1f; 6.1 loader的本質 loader本質是一個方法&#xff0c;接收要處理的資源的內容&#xff0c;處理完畢后給出內容&#xff0c;作為打包結果。 所有的loader&#xff08;例如babel-loader, url-loader等&#xff09;export出一個方…

算法第41天|188.買賣股票的最佳時機IV、309.最佳買賣股票時機含冷凍期、714.買賣股票的最佳時機含手續費

188.買賣股票的最佳時機IV 題目 思路與解法 基于 買賣股票的最佳時機iii&#xff0c;得出的解法。關鍵在于&#xff0c;每一天的賣或者買都由前一天推導而來。 class Solution { public:int maxProfit(int k, vector<int>& prices) {if(prices.size() 0) return …

【AI News | 20250623】每日AI進展

AI Repos 1、tools Strands Agents Tools提供了一個強大的模型驅動方法&#xff0c;通過少量代碼即可構建AI Agent。它提供了一系列即用型工具&#xff0c;彌合了大型語言模型與實際應用之間的鴻溝&#xff0c;涵蓋文件操作、Shell集成、內存管理&#xff08;支持Mem0和Amazon…

Python裝飾器decorators和pytest夾具fixture詳解和使用

此前一直認為fixture就叫python中的裝飾器&#xff0c;學習后才發現decorators才是裝飾器&#xff0c;fixture是pytest框架的夾具&#xff0c;只是通過裝飾器去定義和使用。所以要了解fixture就得先了解python裝飾器。 一、裝飾器(decorators) 1.定義 裝飾器&#xff08;dec…

目標檢測之YOLOv5到YOLOv11——從架構設計和損失函數的變化分析

YOLO&#xff08;You Only Look Once&#xff09;系列作為實時目標檢測領域的標桿性框架&#xff0c;自2016年YOLOv1問世以來&#xff0c;已歷經十余年迭代。本文將聚焦YOLOv5&#xff08;2020年發布&#xff09;到YOLOv11&#xff08;2024年前后&#xff09;的核心技術演進&am…

leetcode:面試題 08.06. 漢諾塔問題

題目鏈接 面試題 08.06. 漢諾塔問題 題目描述 題目解析 當只有一個盤子時&#xff1a;直接從A柱放到C柱即可。當有兩個盤子時&#xff1a;將A柱第一個盤子先放到B柱&#xff0c;再將A柱第二個盤子放到C柱&#xff0c;最后將B柱上的盤子放到C柱子。當有3個盤子時&#xff1a;先…

mybatis-plus一對多關聯查詢

MyBatis-Plus 本身主要關注單表操作&#xff0c;但可以通過幾種方式實現一對多關聯查詢&#xff1a; 1. 使用 XML 映射文件實現 這是最傳統的方式&#xff0c;通過編寫 SQL 和 ResultMap 實現&#xff1a; <!-- UserMapper.xml --> <resultMap id"userWithOrd…

一些想法。。。

1.for里面的局部變量這種還是在for里面定義比較好 比如 for(int i 0;i<n;i){ int num; cin>>num; } 實不相瞞&#xff0c;有一次直接cin了i怎么都沒看出來哪里錯了。。。 2.關于long long 如果發現中間結果大約是10^9&#xff0c;就要考慮int 溢出 即用 long …

遷移科技拆垛工業相機:驅動智能拆碼垛革命,賦能工業自動化新紀元

——將復雜技術轉化為可感知價值&#xff0c;引領行業標桿級解決方案 作為工業自動化領域的品牌策略專家&#xff0c;我深知企業面臨的痛點&#xff1a;拆垛環節效率低下、人工成本高、安全隱患頻發。遷移科技憑借其領先的3D視覺技術&#xff0c;通過拆垛工業相機將抽象參數轉…

Linux筆記---線程控制

1. 線程創建&#xff1a;pthread_create() pthread_create() 是 POSIX 線程庫&#xff08;pthread&#xff09;中用于創建新線程的函數。調用該函數后系統就會啟動一個與主線程并發的線程&#xff0c;并使其跳轉到入口函數處執行。 #include <pthread.h>int pthread_cr…

Ragflow 源碼:ragflow_server.py

目錄 介紹1. 初始化和配置2. 數據庫管理3. 核心功能4. HTTP 服務5. 信號處理6. 調試支持 流程圖系統架構 代碼解釋1. **初始化系統**2. **運行時控制**3. **核心服務** 介紹 ragflow_server.py 是 RAGFlow 項目的主服務器程序&#xff0c;負責啟動和管理 RAGFlow 的核心服務。…

springboot企業級項目開發之項目測試——單元測試!

項目測試 項目測試是對項目的需求和功能進行測試&#xff0c;由測試人員寫出完整的測試用例&#xff0c;再按照測試用例執行測試。項目測試是項目質量的保證&#xff0c;項目測試質量直接決定了當前項目的交付質量。 測試人員在開展測試之前&#xff0c;首先需要進行測試的需…

Linux kdump遠程轉存儲配置手冊教程

一、前言 kdump是一個Linux內核崩潰轉儲機制,當系統崩潰時,它可以捕獲內核的內存轉儲信息,幫助分析崩潰原因。將轉儲文件存儲到遠程位置,便于集中管理和分析。本教程將詳細介紹如何配置kdump將轉儲文件遠程轉存儲。 二、安裝kdump 在大多數Linux發行版中,kdump相關的工…