最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot+websocket實現(xiàn)消息對話功能

 更新時間:2023年09月04日 08:57:14   作者:江 流 兒  
WebSocket是一種在Web應用程序中實現(xiàn)實時雙向通信的技術(shù),它可以用于在線游戲、在線聊天、推送通知、實時監(jiān)控等,并且比傳統(tǒng)的輪詢技術(shù)更加高效和可靠,本文就給大家介紹基于SpringBoot+websocket實現(xiàn)消息對話功能,感興趣的小伙伴可以自己動手試一試

什么是websocket?

WebSocket是一種在Web應用程序中實現(xiàn)實時雙向通信的技術(shù)。Web應用程序通常是基于HTTP協(xié)議的,HTTP是一種請求/響應式的協(xié)議,客戶端發(fā)起請求,服務器響應請求并發(fā)送響應,客戶端收到響應后關(guān)閉連接。這意味著,如果客戶端需要不斷地從服務器獲取更新,它必須定期發(fā)送請求以檢查更新,這將導致大量的網(wǎng)絡流量和不必要的服務器負載。

WebSocket通過在客戶端和服務器之間創(chuàng)建持久化連接,允許雙向?qū)崟r通信。這意味著服務器可以主動向客戶端推送更新,而不必等待客戶端不停地請求。WebSocket連接始于HTTP握手,然后升級到WebSocket協(xié)議。在升級過程中,客戶端和服務器之間的數(shù)據(jù)傳輸方式從HTTP變成了WebSocket協(xié)議,這樣可以降低傳輸數(shù)據(jù)的延遲和提高傳輸數(shù)據(jù)的可靠性。

在WebSocket協(xié)議中,數(shù)據(jù)是以幀的形式傳輸?shù)?,幀包括?shù)據(jù)頭和數(shù)據(jù)體兩個部分。數(shù)據(jù)頭指示數(shù)據(jù)類型,數(shù)據(jù)傳輸?shù)姆较虻刃畔?,?shù)據(jù)體則包括實際傳輸?shù)臄?shù)據(jù)。WebSocket支持文本類型和二進制類型的數(shù)據(jù)。文本類型的數(shù)據(jù)使用UTF-8編碼,而二進制類型的數(shù)據(jù)可以包括任何二進制數(shù)據(jù),如圖像、音頻、視頻等。

WebSockets是非常適合實時通信的技術(shù)。它可以用于在線游戲、在線聊天、推送通知、實時監(jiān)控等,并且比傳統(tǒng)的輪詢技術(shù)更加高效和可靠。對于現(xiàn)代Web應用程序而言,WebSockets已經(jīng)成為不可或缺的技術(shù)之一。

websocket和Socket區(qū)別

區(qū)別WebSocketSocket
應用層協(xié)議基于HTTP協(xié)議,升級為WebSocket協(xié)議沒有明確的應用層協(xié)議,常用于傳輸TCP或UDP數(shù)據(jù)
傳輸數(shù)據(jù)類型支持文本和二進制類型的數(shù)據(jù)通常用于傳輸二進制數(shù)據(jù),如圖片、視頻等
客戶端和服務器通信支持實時雙向通信支持雙向通信,但通常需要進行輪詢或長連接
傳輸效率比傳統(tǒng)的輪詢技術(shù)更加高效和可靠,不會頻繁請求服務器傳輸效率較低,需要進行輪詢或者長連接來保持連接,會頻繁請求服務器
應用場景適用于實時通信,如在線游戲、在線聊天、推送通知、實時監(jiān)控等適用于需要傳輸大量二進制數(shù)據(jù)的場景,如文件傳輸、圖片處理等

代碼部分

引入maven依賴

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

說明:默認版本為1.5.10RELEASE,可自定義版本,加入“<version">"”標簽即可
常量類

package com.dmsdbj.itoo.utils;
public class Constant {
    //webSocket相關(guān)配置
    //鏈接地址
    public static String WEBSOCKETPATHPERFIX = "/ws-push";
    public static String WEBSOCKETPATH = "/endpointWisely";
    //消息代理路徑
    public static String WEBSOCKETBROADCASTPATH = "/topic";
    //前端發(fā)送給服務端請求地址
    public static final String FORETOSERVERPATH = "/welcome";
    //服務端生產(chǎn)地址,客戶端訂閱此地址以接收服務端生產(chǎn)的消息
    public static final String PRODUCERPATH = "/topic/getResponse";
    //點對點消息推送地址前綴
    public static final String P2PPUSHBASEPATH = "/user";
    //點對點消息推送地址后綴,最后的地址為/user/用戶識別碼/msg
    public static final String P2PPUSHPATH = "/msg";
}

接收前端消息實體

package com.dmsdbj.itoo.vo;
public class WiselyMessage {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

后臺發(fā)送消息實體

package com.dmsdbj.itoo.vo;
public class WiselyResponse {
    private String responseMessage;
    public WiselyResponse(String responseMessage){
        this.responseMessage = responseMessage;
    }
    public String getResponseMessage() {
        return responseMessage;
    }
    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }
}

配置websocket

package com.dmsdbj.itoo.config;
import com.dmsdbj.itoo.utils.Constant;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
// @EnableWebSocketMessageBroker注解用于開啟使用STOMP協(xié)議來傳輸基于代理(MessageBroker)的消息,這時候控制器(controller)
// 開始支持@MessageMapping,就像是使用@requestMapping一樣。
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        //注冊一個Stomp的節(jié)點(endpoint),并指定使用SockJS協(xié)議。
        stompEndpointRegistry.addEndpoint(Constant.WEBSOCKETPATH).withSockJS();
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //服務端發(fā)送消息給客戶端的域,多個用逗號隔開
        registry.enableSimpleBroker(Constant.WEBSOCKETBROADCASTPATH, Constant.P2PPUSHBASEPATH);
        //定義一對一推送的時候前綴
        registry.setUserDestinationPrefix(Constant.P2PPUSHBASEPATH);
        //定義websoket前綴
        registry.setApplicationDestinationPrefixes(Constant.WEBSOCKETPATHPERFIX);
    }
}

采用JPA方法進行操作數(shù)據(jù)庫DAO層

package com.dmsdbj.itoo.repository;
import com.dmsdbj.itoo.entity.TbUser;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TbUseRepository extends JpaRepository<TbUser,Long> {}

sql語句

CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL COMMENT '用戶名',
  `password` varchar(32) DEFAULT NULL COMMENT '密碼,加密存儲',
  `phone` varchar(20) DEFAULT NULL COMMENT '注冊手機號',
  `email` varchar(50) DEFAULT NULL COMMENT '注冊郵箱',
  `created` datetime DEFAULT NULL,
  `updated` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`) USING BTREE,
  UNIQUE KEY `phone` (`phone`) USING BTREE,
  UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=18333611875 DEFAULT CHARSET=utf8 COMMENT='用戶表';

TbUser實體類

package com.dmsdbj.itoo.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;
@Entity
@Data
public class TbUser implements Serializable {
    @Id
    private Long id;
    private String username;
    private String password;
    private String phone;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}

Service實現(xiàn)類

@Service
public class TbUseServiceImpl implements TbUseService {
    @Autowired
    TbUseRepository repository;
/**
     * 從數(shù)據(jù)庫查詢用戶,給訂閱者發(fā)送消息
     * @return
     */
    @Override
    public List<Long> send2Users() {
         return repository.findAll().stream().map(s -> s.getId()).collect(Collectors.toList());
    }
}

Service接口類

public interface TbUseService {
 List<Long> send2Users();
}

Façade實現(xiàn)類

@Service
public class TbUseFacadeImpl implements TbUseFacade {
    @Autowired
    TbUseService tbUseService;
@Override
    public List<Long> send2Users() {
       return tbUseService.send2Users();
    }
}

Façade接口類

public interface TbUseFacade {
List<Long> send2Users();
}

Controller類

@Controller
public class SendInfoController {
    @Reference
    TbUseFacade tbUseFacade;
    @Autowired
    private SimpMessagingTemplate template;
    @Resource
    WebSocketService webSocketService;
    @MessageMapping(Constant.FORETOSERVERPATH)//@MessageMapping和@RequestMapping功能類似,用于設(shè)置URL映射地址,瀏覽器向服務器發(fā)起請求,需要通過該地址。
//    @SendTo(Constant.PRODUCERPATH)//如果服務器接受到了消息,就會對訂閱了@SendTo括號中的地址傳送消息。
    public WiselyResponse say(WiselyMessage message) throws Exception {
        List<Long> userId = tbUseFacade.send2Users();
        userId.forEach(s->{
            template.convertAndSendToUser(s.toString(),Constant.P2PPUSHPATH, new WiselyResponse(message.getName()));
        });
        return null;
    }
}

前端頁面
sendws.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Spring Boot+WebSocket+廣播式</title>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">貌似你的瀏覽器不支持websocket</h2></noscript>
<div>
    <div>
        <button id="connect" onclick="connect();">連接</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">斷開連接</button>
    </div>
    <div id="conversationDiv">
        <label>輸入要發(fā)送的消息</label><input type="text" id="name" />
        <button id="sendName" onclick="sendName();">發(fā)送</button>
        <p id="response"></p>
        <p id="response1"></p>
    </div>
</div>
<!--<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>-->
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script th:inline="javascript">
    var stompClient = null;
    //此值有服務端傳遞給前端,實現(xiàn)方式?jīng)]有要求
    //var userId = [[${userId}]];
    var userId = 'd892bf12bf7d11e793b69c5c8e6f60fb';
    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
        $('#response').html();
    }
    function connect() {
        var socket = new SockJS('/endpointWisely'); //1連接SockJS的endpoint是“endpointWisely”,與后臺代碼中注冊的endpoint要一樣。
        stompClient = Stomp.over(socket);//2創(chuàng)建STOMP協(xié)議的webSocket客戶端。
        stompClient.connect({}, function(frame) {//3連接webSocket的服務端。
            setConnected(true);
            console.log('開始進行連接Connected: ' + frame);
        });
    }
    function disconnect() {
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }
    function sendName() {
        var name = $('#name').val();
        console.log(name);
        //通過stompClient.send()向地址為"/welcome"的服務器地址發(fā)起請求,與@MessageMapping里的地址對應。因為我們配置了registry.setApplicationDestinationPrefixes(Constant.WEBSOCKETPATHPERFIX);所以需要增加前綴/ws-push/
        stompClient.send("/ws-push/welcome", {}, JSON.stringify({ 'name': name }));
    }
</script>
</body>
</html>

subws.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Spring Boot+WebSocket+廣播式</title>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">貌似你的瀏覽器不支持websocket</h2></noscript>
<div>
    <div>
        <button id="connect" onclick="connect();">連接</button>
        <button id="disconnect" disabled="disabled" onclick="disconnect();">斷開連接</button>
    </div>
    <div id="conversationDiv">
        <label>輸入你的userId</label><input type="text" id="userId" />
        <button id="subMsg" onclick="subMsg();">訂閱消息</button>
        <p id="response"></p>
        <p id="response1"></p>
    </div>
</div>
<!--<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>-->
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script th:inline="javascript">
    var stompClient = null;
    //此值有服務端傳遞給前端,實現(xiàn)方式?jīng)]有要求
    //var userId = [[${userId}]];
    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
        $('#response').html();
    }
    function connect() {
        var socket = new SockJS('/endpointWisely'); //1連接SockJS的endpoint是“endpointWisely”,與后臺代碼中注冊的endpoint要一樣。
        stompClient = Stomp.over(socket);//2創(chuàng)建STOMP協(xié)議的webSocket客戶端。
        stompClient.connect({}, function(frame) {//3連接webSocket的服務端。
            setConnected(true);
            console.log('開始進行連接Connected: ' + frame);
            //4通過stompClient.subscribe()訂閱服務器的目標是'/topic/getResponse'發(fā)送過來的地址,與@SendTo中的地址對應。
            /*stompClient.subscribe('/topic/getResponse', function(respnose){
                showResponse(JSON.parse(respnose.body).responseMessage);
            });*/
        });
    }
    function subMsg() {
        var userId = $('#userId').val();
        console.log(userId);
        $.ajax({
            type: 'GET',
            url: '/user/insert?userId='+userId,
            //data: userId,
            success: function (data) {
                console.log(data);
                //4通過stompClient.subscribe()訂閱服務器的目標是'/user/' + userId + '/msg'接收一對一的推送消息,其中userId由服務端傳遞過來,用于表示唯一的用戶,通過此值將消息精確推送給一個用戶
                stompClient.subscribe('/user/' + userId + '/msg', function(respnose){
                    console.log(respnose);
                    showResponse1(JSON.parse(respnose.body).responseMessage);
                });
            }
        });
    }
    function disconnect() {
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }
    function showResponse1(message) {
        var response = $("#response1");
        response.html(message);
    }
</script>
</body>
</html>

實戰(zhàn)應用

①啟動springboot-dubbo-service的主啟動類“SpringbootDubboServiceApplication”
②啟動springboot-dubbo-web的主啟動類“SpringbootDubboWebApplication”
③訪問
http://localhost:9000/sendws 發(fā)送消息方
http://localhost:9000/subws 訂閱消息方
④分別進行連接操作
訂閱方輸入訂閱方的連接賬號userid,后期就可以接收發(fā)送端發(fā)送的消息
連接后的結(jié)果展示

以上就是SpringBoot+websocket實現(xiàn)消息對話功能的詳細內(nèi)容,更多關(guān)于SpringBoot websocket消息對話的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringMVC框架的介紹與使用詳解

    SpringMVC框架的介紹與使用詳解

    SpringMVC?是一種基于?Java?的實現(xiàn)?MVC?設(shè)計模型的請求驅(qū)動類型的輕量級?Web?框架,跟Spring,Mybatis框架并稱為ssm,這篇文章主要介紹了SpringMVC框架的介紹與使用,需要的朋友可以參考下
    2022-08-08
  • MyBatis反向生成Example類的使用方式

    MyBatis反向生成Example類的使用方式

    今天小編就為大家分享一篇MyBatis反向生成Example類的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Springboot 如何設(shè)置啟動內(nèi)存

    Springboot 如何設(shè)置啟動內(nèi)存

    這篇文章主要介紹了Springboot 如何設(shè)置啟動內(nèi)存,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java實現(xiàn)固定時段倒計時的示例代碼

    java實現(xiàn)固定時段倒計時的示例代碼

    這篇文章主要為大家詳細介紹了java實現(xiàn)固定時段倒計時,可以在每隔一定時間給出時間倒計時提示,文中的示例代碼講解詳細,需要的可以了解下
    2025-08-08
  • springboot?sleuth?日志跟蹤問題記錄

    springboot?sleuth?日志跟蹤問題記錄

    Spring?Cloud?Sleuth是一個在應用中實現(xiàn)日志跟蹤的強有力的工具,使用Sleuth庫可以應用于計劃任務?、多線程服務或復雜的Web請求,尤其是在一個由多個服務組成的系統(tǒng)中,這篇文章主要介紹了springboot?sleuth?日志跟蹤,需要的朋友可以參考下
    2023-07-07
  • 解決druid監(jiān)控頁面SQL不顯示的問題

    解決druid監(jiān)控頁面SQL不顯示的問題

    這篇文章主要介紹了解決druid監(jiān)控頁面SQL不顯示的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java使用es查詢的示例代碼

    java使用es查詢的示例代碼

    本篇文章主要介紹了java使用es查詢的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • SpringBoot+Docker+K8s云原生部署全流程(從零到發(fā)布)

    SpringBoot+Docker+K8s云原生部署全流程(從零到發(fā)布)

    本文詳解了SpringBoot項目從開發(fā)到基于Docker容器化,再通過K8s實現(xiàn)云原生部署的全流程,涵蓋環(huán)境搭建、鏡像構(gòu)建、服務部署及CI/CD自動化,提升應用部署效率與可維護性,需要的朋友跟隨小編一起學習吧
    2025-08-08
  • Spring?boot如何在IDEA中讓一個應用在不同的端口多次啟動詳解

    Spring?boot如何在IDEA中讓一個應用在不同的端口多次啟動詳解

    在開發(fā)過程中,SpringBoot項目的多端口啟動是一個實用的需求,特別是在進行并發(fā)測試或者隔離環(huán)境時,這篇文章主要介紹了Spring?boot如何在IDEA中讓一個應用在不同的端口多次啟動的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • RabbitMQ的ACK確認機制保障消費端消息的可靠性詳解

    RabbitMQ的ACK確認機制保障消費端消息的可靠性詳解

    這篇文章主要介紹了RabbitMQ的ACK確認機制保障消費端消息的可靠性詳解,簡單來說,就是你必須關(guān)閉 RabbitMQ 的自動ack ,可以通過一個 api 來調(diào)用就行,然后每次你自己代碼里確保處理完的時候,再在程序里 ack 一把,需要的朋友可以參考下
    2023-12-12

最新評論

峨眉山市| 隆化县| 建始县| 新源县| 长泰县| 荥经县| 广平县| 抚宁县| 图们市| 旺苍县| 赤壁市| 宜黄县| 红原县| 乌审旗| 镇平县| 丰原市| 汤原县| 陇川县| 克东县| 毕节市| 凤台县| 建湖县| 洪江市| 溧阳市| 通化市| 乳山市| 年辖:市辖区| 措美县| 宜都市| 会泽县| 汝南县| 桐城市| 英德市| 玉溪市| 阿尔山市| 霍林郭勒市| 桐庐县| 金川县| 麻江县| 广安市| 京山县|