国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

效果圖

1 輸入臨時(shí)名字充當(dāng)賬號使用
SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口,spring boot,vue.js,websocket

2 進(jìn)入聊天窗口
SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口,spring boot,vue.js,websocket

3 發(fā)送消息 (復(fù)制一個(gè)頁面,輸入其他名字,方便展示效果)
SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口,spring boot,vue.js,websocket

4 其他窗口效果
SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口,spring boot,vue.js,websocket

代碼實(shí)現(xiàn)

后端SpringBoot項(xiàng)目,自行創(chuàng)建

pom依賴

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>2.7.12</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.23</version>
        </dependency>

WebSocketConfig.java

package com.dark.wsdemo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * WebSocket配置類。開啟WebSocket的支持
 */
@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

WebSocketServer.java

package com.dark.wsdemo.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dark.wsdemo.vo.MessageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * WebSocket的操作類
 */
@Component
@Slf4j
@ServerEndpoint("/websocket/{name}")
public class WebSocketServer {

    /**
     * 靜態(tài)變量,用來記錄當(dāng)前在線連接數(shù),線程安全的類。
     */
    private static final AtomicInteger onlineSessionClientCount = new AtomicInteger(0);

    /**
     * 存放所有在線的客戶端
     */
    private static final Map<String, Session> onlineSessionClientMap = new ConcurrentHashMap<>();

    /**
     * 連接 name 和連接會話
     */
    private String name;

    @OnOpen
    public void onOpen(@PathParam("name") String name, Session session) {
        /**
         * session.getId():當(dāng)前session會話會自動生成一個(gè)id,從0開始累加的。
         */
        Session beforeSession = onlineSessionClientMap.get(name);
        if (beforeSession != null) {
            //在線數(shù)減1
            onlineSessionClientCount.decrementAndGet();
            log.info("連接已存在,關(guān)閉之前的連接 ==> session_id = {}, name = {}。", beforeSession.getId(), name);
            //通知之前其他地方連接被擠掉
            sendToOne(name, "您的賬號在其他地方登錄,您被迫下線。");
            // 從 Map中移除
            onlineSessionClientMap.remove(name);
            //關(guān)閉之前的連接
            try {
                beforeSession.close();
            } catch (Exception e) {
                log.error("關(guān)閉之前的連接異常,異常信息為:{}", e.getMessage());
            }
        }
        log.info("連接建立中 ==> session_id = {}, name = {}", session.getId(), name);
        onlineSessionClientMap.put(name, session);

        //在線數(shù)加1
        onlineSessionClientCount.incrementAndGet();
        this.name = name;
        sendToOne(name, "連接成功");
        log.info("連接建立成功,當(dāng)前在線數(shù)為:{} ==> 開始監(jiān)聽新連接:session_id = {}, name = {}。", onlineSessionClientCount, session.getId(), name);
    }


    @OnClose
    public void onClose(@PathParam("name") String name, Session session) {
        if (name == null || name.equals("")) {
            name = this.name;
        }
        // 從 Map中移除
        onlineSessionClientMap.remove(name);

        //在線數(shù)減1
        onlineSessionClientCount.decrementAndGet();
        log.info("連接關(guān)閉成功,當(dāng)前在線數(shù)為:{} ==> 關(guān)閉該連接信息:session_id = {}, name = {}。", onlineSessionClientCount, session.getId(), name);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        JSONObject jsonObject = JSON.parseObject(message);
        String toname = jsonObject.getString("name");
        String msg = jsonObject.getString("message");
        log.info("服務(wù)端收到客戶端消息 ==> fromname = {}, toname = {}, message = {}", name, toname, message);

        /**
         * 模擬約定:如果未指定name信息,則群發(fā),否則就單獨(dú)發(fā)送
         */
        if (toname == null || toname == "" || "".equalsIgnoreCase(toname)) {
            sendToAll(msg);
        } else {
            sendToOne(toname, msg);
        }
    }

    /**
     * 發(fā)生錯(cuò)誤調(diào)用的方法
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket發(fā)生錯(cuò)誤,錯(cuò)誤信息為:" + error.getMessage());
        error.printStackTrace();
    }

    /**
     * 群發(fā)消息
     *
     * @param message 消息
     */
    private void sendToAll(String message) {
        // 遍歷在線map集合
        onlineSessionClientMap.forEach((onlineName, toSession) -> {
            // 排除掉自己
            if (!name.equalsIgnoreCase(onlineName)) {
                log.info("服務(wù)端給客戶端群發(fā)消息 ==> name = {}, toname = {}, message = {}", name, onlineName, message);
                MessageVo messageVo = new MessageVo();
                messageVo.setFrom(name);
                messageVo.setDate(new Date());
                messageVo.setMessage(message);
                toSession.getAsyncRemote().sendText(JSON.toJSONString(messageVo));
            }
        });
    }

    /**
     * 指定發(fā)送消息
     *
     * @param toName
     * @param message
     */
    private void sendToOne(String toName, String message) {
        // 通過name查詢map中是否存在
        Session toSession = onlineSessionClientMap.get(toName);
        if (toSession == null) {
            log.error("服務(wù)端給客戶端發(fā)送消息 ==> toname = {} 不存在, message = {}", toName, message);
            return;
        }
        // 異步發(fā)送
        log.info("服務(wù)端給客戶端發(fā)送消息 ==> toname = {}, message = {}", toName, message);
        MessageVo messageVo = new MessageVo();
        messageVo.setFrom(name);
        messageVo.setDate(new Date());
        messageVo.setMessage(message);
        toSession.getAsyncRemote().sendText(JSON.toJSONString(messageVo));

    }

}

MessageVo.java

package com.dark.wsdemo.vo;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;

@Data
public class MessageVo {
    private String from;
    //json時(shí)候格式化為時(shí)間格式
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date date;
    private String message;
}

Vue代碼實(shí)現(xiàn)

App.vue文章來源地址http://www.zghlxwxcb.cn/news/detail-707926.html

<template>
  <div id="app">
    <!-- Modal Dialog -->
    <div class="modal" v-if="!username">
      <div class="modal-content">
        <h2>請輸入你的名字</h2>
        <input type="text" v-model="inputUsername" />
        <button @click="setUsername">確定</button>
      </div>
    </div>

    <!-- Chat Box -->
    <div class="chat-box" v-if="username">
      <div class="chat-history">
        <div v-for="msg in messages" :key="msg.id" :class="[msg.type, 'message']">
          <div class="info">
            <span class="from">{{ msg.from }}</span>
            <span class="date">{{ msg.date }}</span>
          </div>
          <div class="bubble">
            {{ msg.message }}
          </div>
        </div>
      </div>
      <div class="chat-input">
        <input type="text" v-model="inputMessage" @keyup.enter="sendMessage" placeholder="請輸入消息..."/>
        <button @click="sendMessage">發(fā)送</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      inputMessage: '',
      inputUsername: '',
      messages: [],
      username: '',
      ws: null,
    };
  },
  methods: {
    setUsername() {
      if (this.inputUsername.trim() === '') return;
      this.username = this.inputUsername.trim();
      this.ws = new WebSocket(`ws://localhost:8081/websocket/${this.username}`);

      this.ws.addEventListener('message', (event) => {
        const data = JSON.parse(event.data);
        this.messages.push({ ...data, type: 'left', id: this.messages.length });
      });
    },
    sendMessage() {
      if (this.inputMessage.trim() === '') return;
      const message = {
        from: this.username,
        date: new Date().toLocaleString(),
        message: this.inputMessage.trim(),
      };
      this.ws.send(JSON.stringify(message));
      this.messages.push({ ...message, type: 'right', id: this.messages.length });
      this.inputMessage = '';
    },
  },
};
</script>

<style>
/* Modal Styles */
.modal {
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 9999;
}

.modal-content {
  background-color: #fff;
  padding: 20px;
  width: 300px;
  text-align: center;
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* Chat Box Styles */
#app {
  background-color: #f2f2f2;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  font-family: Arial, sans-serif;
}

.chat-box {
  box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
  width: 300px;
  height: 400px;
  border-radius: 8px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.chat-history {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  background-color: #fff;
}

.message {
  padding: 5px 0;
}

.info {
  font-size: 12px;
  color: gray;
  margin-bottom: 4px;
}

.left .bubble {
  background-color: #e6e6e6;
  border-radius: 15px;
  padding: 12px;
  display: inline-block;
}

.right .bubble {
  background-color: #007bff;
  color: white;
  border-radius: 15px;
  padding: 12px;
  display: inline-block;
  margin-left: auto;
}

.chat-input {
  display: flex;
  padding: 10px;
  background-color: #f7f7f7;
  border-top: 1px solid #ccc;
}

input {
  flex: 1;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-right: 10px;
}

button {
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}
</style>

到了這里,關(guān)于SpringBoot+Vue 整合websocket實(shí)現(xiàn)簡單聊天窗口的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • springboot整合tio-websocket方案實(shí)現(xiàn)簡易聊天

    springboot整合tio-websocket方案實(shí)現(xiàn)簡易聊天

    一、導(dǎo)包(導(dǎo)入TIO的兩個(gè)依賴,其他必要依賴不贅述) 二、yml配置 三、配置參數(shù) 四、實(shí)現(xiàn)一些監(jiān)聽類 1.ServerAioListener監(jiān)聽 2.IpStatListener監(jiān)聽(這個(gè)可選) 3.WsServerAioListener監(jiān)聽 4.IWsMsgHandler攔截(里面邏輯根據(jù)具體業(yè)務(wù),但是必須實(shí)現(xiàn)這個(gè),不然啟動報(bào)錯(cuò)) 五、一些消息體(根據(jù)

    2024年02月14日
    瀏覽(19)
  • springboot+websocket實(shí)現(xiàn)簡單的聊天室

    springboot+websocket實(shí)現(xiàn)簡單的聊天室

    HTML HTML是創(chuàng)建和構(gòu)造網(wǎng)頁的標(biāo)準(zhǔn)標(biāo)記語言。它使用一組標(biāo)記標(biāo)簽描述網(wǎng)頁上的內(nèi)容結(jié)構(gòu)。HTML文檔由HTML元素的嵌套結(jié)構(gòu)組成,每個(gè)元素由尖括號( )括起的標(biāo)簽表示。這些元素定義了網(wǎng)頁的各個(gè)部分,如標(biāo)題、段落、圖像、鏈接、表單等。 JavaScript JavaScript是一種高級、解釋性

    2024年01月21日
    瀏覽(23)
  • Vue+Websocket<簡單實(shí)現(xiàn)聊天功能>

    Vue+Websocket<簡單實(shí)現(xiàn)聊天功能>

    此篇文章是針對 Websocket 的簡單了解和應(yīng)用,利用 Nodejs 簡單搭建一個(gè)服務(wù)器加以實(shí)現(xiàn)。 首先創(chuàng)建一個(gè) vue 項(xiàng)目,會vue的我就不必多說了; 然后再創(chuàng)建一個(gè) server 文件夾,在終端上打開該文件夾,輸入 vue init (一直敲 \\\"回車\\\" 鍵),最后再建一個(gè) server.js 文件,如下圖 代碼如下

    2023年04月22日
    瀏覽(18)
  • Springboot + Websocket的集成實(shí)現(xiàn)簡單的聊天室功能

    Springboot + Websocket的集成實(shí)現(xiàn)簡單的聊天室功能

    WebSocket是一種網(wǎng)絡(luò)通信協(xié)議,它可以在單個(gè)TCP連接上實(shí)現(xiàn)雙向(全雙工)通信。WebSocket使用HTML5標(biāo)準(zhǔn),并且可以在客戶端和服務(wù)器之間建立持久連接,這意味著連接在瀏覽器刷新或關(guān)閉后仍然保持打開狀態(tài)。 WebSocket的主要優(yōu)點(diǎn)包括: 1. 雙向通信:WebSocket支持客戶端和服務(wù)器之

    2024年03月21日
    瀏覽(27)
  • springboot + websocket對接文心一言接口實(shí)現(xiàn)簡單上下文聊天(貼代碼)

    springboot + websocket對接文心一言接口實(shí)現(xiàn)簡單上下文聊天(貼代碼)

    如題,第一次用websocket,做了個(gè)這玩意,只做了上下文的聊天,沒做流式。 中間還有個(gè)低級報(bào)錯(cuò)但卡了好久,具體可以看【錯(cuò)誤記錄】websocket連接失敗,但后端毫無反應(yīng),還有【錯(cuò)誤記錄】ruoyi-vue@Autowired注入自定義mapper時(shí)為null解決 ,感興趣可前往觀看。 實(shí)際上我后端用的

    2024年02月07日
    瀏覽(25)
  • 基于 Vue3 和 WebSocket 實(shí)現(xiàn)的簡單網(wǎng)頁聊天應(yīng)用

    基于 Vue3 和 WebSocket 實(shí)現(xiàn)的簡單網(wǎng)頁聊天應(yīng)用

    一個(gè)基于Vue3和WebSocket的簡易網(wǎng)絡(luò)聊天室項(xiàng)目,包括服務(wù)端和客戶端部分。 項(xiàng)目地址 websocket-chat 下面是項(xiàng)目的主要組成部分和功能: 項(xiàng)目結(jié)構(gòu) 功能特性 私聊功能:用戶可以選擇聯(lián)系人進(jìn)行一對一私聊,發(fā)送即時(shí)消息。 群聊功能:用戶可以加入群組,與群組成員進(jìn)行群聊。

    2024年02月03日
    瀏覽(28)
  • SpringBoot+Netty+Vue+Websocket實(shí)現(xiàn)在線推送/聊天系統(tǒng)

    SpringBoot+Netty+Vue+Websocket實(shí)現(xiàn)在線推送/聊天系統(tǒng)

    ok,那么今天的話也是帶來這個(gè)非常常用的一個(gè)技術(shù),那就是咱們完成nutty的一個(gè)應(yīng)用,今天的話,我會介紹地很詳細(xì),這樣的話,拿到這個(gè)博文的代碼就基本上可以按照自己的想法去構(gòu)建自己的一個(gè)在線應(yīng)用了。比如聊天,在線消息推送之類的。其實(shí)一開始我原來的想法做在

    2024年02月03日
    瀏覽(26)
  • SpringBoot和Vue2集成WebSocket,實(shí)現(xiàn)聊天室功能

    springboot集成websocket實(shí)現(xiàn)聊天室的功能。如有不足之處,還望大家斧正。

    2024年01月23日
    瀏覽(27)
  • SpringBoot+Vue整合WebSocket實(shí)現(xiàn)實(shí)時(shí)通訊

    SpringBoot+Vue整合WebSocket實(shí)現(xiàn)實(shí)時(shí)通訊

    ????????在開發(fā)過程中,我們經(jīng)常遇到需要對前臺的列表數(shù)據(jù),實(shí)現(xiàn)實(shí)時(shí)展示最新的幾條數(shù)據(jù),或者是調(diào)度的任務(wù)進(jìn)度條實(shí)現(xiàn)實(shí)時(shí)的刷新......,而對于這種需求,無狀態(tài)的http協(xié)議顯然無法滿足我們的需求,于是websocket協(xié)議應(yīng)運(yùn)而生。websocket協(xié)議本質(zhì)上是一個(gè)基于tcp的協(xié)議

    2024年02月13日
    瀏覽(24)
  • Vue + Element-Plus + SpringBoot + WebSocket實(shí)現(xiàn)簡易網(wǎng)絡(luò)聊天室

    Vue + Element-Plus + SpringBoot + WebSocket實(shí)現(xiàn)簡易網(wǎng)絡(luò)聊天室

    項(xiàng)目流程圖 1. 前端搭建: ? ? ? ? 前端用Vue+Element-Plus 來搭建,由登錄頁面和聊天頁面組成 1.1 登錄頁面 ? ? ? ? 由一個(gè)昵稱輸入框組成,用戶輸入自己的昵稱若昵稱和別的用戶不重復(fù),則可進(jìn)入聊天室,否則提示錯(cuò)誤并請重新輸入。 ????????這段代碼是一個(gè)Vue.js組件的

    2024年02月03日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包