Jadual Kandungan
1. Pembinaan pangkalan data
2 2.1 Memperkenalkan kebergantungan utama
2.2 Kelas konfigurasi WebSocket
Fungsi WebSocketConfig adalah untuk mendayakan pemantauan WebSocket
2.4 Kelas kawalan untuk menghantar mesej
Pada ketika ini, bahagian belakang ialah secara amnya dikonfigurasikan.
Artikel ini menggunakan templat vue-admin-template-master untuk membina bahagian hadapan ruang sembang
Letakkan fail berikut dalam folder api
3.3 Isytiharkan objek websocket dalam App.vue
App.vue
"+msg.data+"
3.5 Kesan akhir
Gunakan dua penyemak imbas berbeza untuk log masuk ke akaun admin dan ujian Chat dengan akaun wskh, kesannya adalah seperti berikut (admin berada di sebelah kiri):
Rumah Java javaTutorial Cara menggunakan WebSocket+SpringBoot+Vue untuk membina bilik sembang web yang ringkas

Cara menggunakan WebSocket+SpringBoot+Vue untuk membina bilik sembang web yang ringkas

May 16, 2023 am 10:46 AM
vue websocket springboot

1. Pembinaan pangkalan data

Jadual pengguna yang sangat mudah, tambahkan dua pengguna admin dan wskh

Cara menggunakan WebSocket+SpringBoot+Vue untuk membina bilik sembang web yang ringkas

2 2.1 Memperkenalkan kebergantungan utama

<dependency>            
    <groupId>org.springframework.boot</groupId>            
    <artifactId>spring-boot-starter-websocket</artifactId>       
</dependency>
Salin selepas log masuk
2.2 Kelas konfigurasi WebSocket
Fungsi WebSocketConfig adalah untuk mendayakan pemantauan WebSocket
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/** 
* @Author:WSKH 
* @ClassName:WebSocketConfig 
* @ClassType:配置类 
* @Description:WebSocket配置类 
* @Date:2022/1/25/12:21 
* @Email:1187560563@qq.com 
* @Blog:https://blog.csdn.net/weixin_51545953?type=blog 
*/

@Configuration
public class WebSocketConfig {
    /** * 开启webSocket * @return */ 
    @Bean 
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter(); 
    }
}
Salin selepas log masuk

WebSocketServer menulis beberapa acara, seperti menghantar peristiwa mesej sambungan , acara, menutup acara sambungan, dsb.

import com.wskh.chatroom.util.FastJsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.EOFException;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {
    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);

    private static int onlineCount = 0;

    private static ConcurrentHashMap<String,WebSocketServer> webSocketServerMap = new ConcurrentHashMap<>();

    private Session session;

    private String sid;


    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        this.sid = sid;
        this.session = session;
        webSocketServerMap.put(sid, this);
        addOnlineCount();
        log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
        try {
            sendInfo("openSuccess:"+webSocketServerMap.keySet());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public void onClose() {
        webSocketServerMap.remove(sid);
        subOnlineCount();
        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
        try {
            sendInfo("openSuccess:"+webSocketServerMap.keySet());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        if("ping".equals(message)) {
            sendInfo(sid, "pong");
        }
        if(message.contains(":")) {
            String[] split = message.split(":");
            sendInfo(split[0], "receivedMessage:"+sid+":"+split[1]);
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        if(error instanceof EOFException) {
            return;
        }
        if(error instanceof IOException && error.getMessage().contains("已建立的连接")) {
            return;
        }
        log.error("发生错误", error);
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        synchronized (session) {
            this.session.getBasicRemote().sendText(message);
        }
    }

    public static void sendObject(Object obj) throws IOException {
        sendInfo(FastJsonUtils.convertObjectToJSON(obj));
    }

    public static void sendInfo(String sid,String message) throws IOException {
        WebSocketServer socketServer = webSocketServerMap.get(sid);
        if(socketServer != null) {
            socketServer.sendMessage(message);
        }
    }

    public static void sendInfo(String message) throws IOException {
        for(String sid : webSocketServerMap.keySet()) {
            webSocketServerMap.get(sid).sendMessage(message);
        }
    }

    public static void sendInfoByUserId(Long userId,Object message) throws IOException {
        for(String sid : webSocketServerMap.keySet()) {
            String[] sids =  sid.split("id");
            if(sids.length == 2) {
                String id = sids[1];
                if(userId.equals(Long.parseLong(id))) {
                    webSocketServerMap.get(sid).sendMessage(FastJsonUtils.convertObjectToJSON(message));
                }
            }
        }
    }

    public static Session getWebSocketSession(String sid) {
        if(webSocketServerMap.containsKey(sid)) {
            return webSocketServerMap.get(sid).session;
        }
        return null;
    }

    public static synchronized void addOnlineCount() {
        onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        onlineCount--;
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
}
Salin selepas log masuk

2.3 Mengkonfigurasi merentas domain

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    // 跨域配置
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }

}
Salin selepas log masuk
2.4 Kelas kawalan untuk menghantar mesej
/**
 * @Author:WSKH
 * @ClassName:MsgController
 * @ClassType:控制类
 * @Description:信息控制类
 * @Date:2022/1/25/12:47
 * @Email:1187560563@qq.com
 * @Blog:https://blog.csdn.net/weixin_51545953?type=blog
 */
@ApiModel("信息控制类")
@RestController
@RequestMapping("/chatroom/msg")
public class MsgController {
    @ApiOperation("发送信息方法")
    @PostMapping("/sendMsg")
    public R sendMsg(String msg) throws IOException {
        WebSocketServer.sendInfo(msg);
        return R.ok().message("发送成功");
    }
}
Salin selepas log masuk
Pada ketika ini, bahagian belakang ialah secara amnya dikonfigurasikan.

3. Pembinaan bahagian hadapan

Artikel ini menggunakan templat vue-admin-template-master untuk membina bahagian hadapan ruang sembang

3.1 Soket web fail tersuai .js

Letakkan fail berikut dalam folder api

//websocket.js
import Vue from &#39;vue&#39;

// 1、用于保存WebSocket 实例对象
export const WebSocketHandle = undefined

// 2、外部根据具体登录地址实例化WebSocket 然后回传保存WebSocket
export const WebsocketINI = function(websocketinstance) {
  this.WebSocketHandle = websocketinstance
  this.WebSocketHandle.onmessage = OnMessage
}

// 3、为实例化的WebSocket绑定消息接收事件:同时用于回调外部各个vue页面绑定的消息事件
// 主要使用WebSocket.WebSocketOnMsgEvent_CallBack才能访问  this.WebSocketOnMsgEvent_CallBack 无法访问很诡异
const OnMessage = function(msg) {
  // 1、消息打印
  // console.log(&#39;收到消息:&#39;, msg)

  // 2、如果外部回调函数未绑定 结束操作
  if (!WebSocket.WebSocketOnMsgEvent_CallBack) {
    console.log(WebSocket.WebSocketOnMsgEvent_CallBack)
    return
  }

  // 3、调用外部函数
  WebSocket.WebSocketOnMsgEvent_CallBack(msg)
}

// 4、全局存放外部页面绑定onmessage消息回调函数:注意使用的是var
export const WebSocketOnMsgEvent_CallBack = undefined

// 5、外部通过此绑定方法 来传入的onmessage消息回调函数
export const WebSocketBandMsgReceivedEvent = function(receiveevent) {
  WebSocket.WebSocketOnMsgEvent_CallBack = receiveevent
}

// 6、封装一个直接发送消息的方法:
export const Send = function(msg) {
  if (!this.WebSocketHandle || this.WebSocketHandle.readyState !== 1) {
    // 未创建连接 或者连接断开 无法发送消息
    return
  }
  this.WebSocketHandle.send(msg)// 发送消息
}

// 7、导出配置
const WebSocket = {
  WebSocketHandle,
  WebsocketINI,
  WebSocketBandMsgReceivedEvent,
  Send,
  WebSocketOnMsgEvent_CallBack
}

// 8、全局绑定WebSocket
Vue.prototype.$WebSocket = WebSocket
Salin selepas log masuk
Cara menggunakan WebSocket+SpringBoot+Vue untuk membina bilik sembang web yang ringkas3.2 Perkenalkan websocket secara global dalam main.js

import &#39;@/utils/websocket&#39; // 全局引入 WebSocket 通讯组件
Salin selepas log masuk
3.3 Isytiharkan objek websocket dalam App.vue
App.vue
<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
  import {getInfo} from &#39;./api/login.js&#39;;
  import {getToken} from &#39;./utils/auth.js&#39;
  export default {
    name: &#39;App&#39;,
    mounted() {
      // 每3秒检测一次websocket连接状态 未连接 则尝试连接 尽量保证网站启动的时候 WebSocket都能正常长连接
      setInterval(this.WebSocket_StatusCheck, 3000)
      // 绑定消息回调事件
      this.$WebSocket.WebSocketBandMsgReceivedEvent(this.WebSocket_OnMesage)
      // 初始化当前用户信息
      this.token = getToken()
      getInfo(this.token).then((rep)=>{
        console.log(rep)
        this.userName = rep.data.name
      }).catch((error)=>{
        console.log(error)
      })
    },
    data(){
      return{

      }
    },
    methods: {

      // 实际消息回调事件
      WebSocket_OnMesage(msg) {
        console.log(&#39;收到服务器消息:&#39;, msg.data)
        console.log(msg)
        let chatDiv = document.getElementById("chatDiv")
        let newH3 = document.createElement("div")
        if(msg.data.indexOf(&#39;openSuccess&#39;)>=0){
			// 忽略连接成功消息提示
        }else{
          if(msg.data.indexOf(this.userName)==0){
            // 说明是自己发的消息,应该靠右边悬浮
            newH3.innerHTML = "<div style=&#39;width:100%;text-align: right;&#39;><h4 id="msg-data">"+msg.data+"</h4></div>"
          }else{
            newH3.innerHTML = "<div style=&#39;width:100%;text-align: left;&#39;><h4 id="msg-data">"+msg.data+"</h4></div>"
          }
        }
        chatDiv.appendChild(newH3)
      },

      // 1、WebSocket连接状态检测:
      WebSocket_StatusCheck() {
        if (!this.$WebSocket.WebSocketHandle || this.$WebSocket.WebSocketHandle.readyState !== 1) {
          console.log(&#39;Websocket连接中断,尝试重新连接:&#39;)
          this.WebSocketINI()
        }
      },

      // 2、WebSocket初始化:
      async WebSocketINI() {
        // 1、浏览器是否支持WebSocket检测
        if (!(&#39;WebSocket&#39; in window)) {
          console.log(&#39;您的浏览器不支持WebSocket!&#39;)
          return
        }

        let DEFAULT_URL = "ws://" + &#39;127.0.0.1:8002&#39; + &#39;/websocket/&#39; + new Date().getTime()

        // 3、创建Websocket连接
        const tmpWebsocket = new WebSocket(DEFAULT_URL)

        // 4、全局保存WebSocket操作句柄:main.js 全局引用
        this.$WebSocket.WebsocketINI(tmpWebsocket)

        // 5、WebSocket连接成功提示
        tmpWebsocket.onopen = function(e) {
          console.log(&#39;webcoket连接成功&#39;)
        }

        //6、连接失败提示
        tmpWebsocket.onclose = function(e) {
          console.log(&#39;webcoket连接关闭:&#39;, e)
        }
      }

    }
  }
</script>
Salin selepas log masuk

3.4 Antara muka bilik sembang.vue

<template>
  <div>
    <div >聊天内容:</div>
    <div  id="chatDiv">

    </div>
    <div >聊天输入框:</div>
    <el-input v-model="text">

    </el-input>
    <el-button @click="sendMsg">点击发送</el-button>
  </div>
</template>

<script>
  import {getInfo} from &#39;../../api/login.js&#39;;
  import {getToken} from &#39;../../utils/auth.js&#39;
  import msgApi from &#39;../../api/msg.js&#39;
  export default {
    mounted() {
      //
      this.token = getToken()
      getInfo(this.token).then((rep)=>{
        console.log(rep)
        this.userName = rep.data.name
      }).catch((error)=>{
        console.log(error)
      })
    },
    data() {
      return {
        text: "",
        token:"",
        userName:"",
      }
    },
    methods: {
      sendMsg(){
        let msg = this.userName+":"+this.text
        msgApi.sendMsg(msg).then((rep)=>{

        }).catch((error)=>{

        })
        this.text = ""
      }
    }
  }
</script>

<style scoped="true">
  .selfMsg{
    float: right;
  }
</style>
Salin selepas log masuk
3.5 Kesan akhir
Gunakan dua penyemak imbas berbeza untuk log masuk ke akaun admin dan ujian Chat dengan akaun wskh, kesannya adalah seperti berikut (admin berada di sebelah kiri):

Atas ialah kandungan terperinci Cara menggunakan WebSocket+SpringBoot+Vue untuk membina bilik sembang web yang ringkas. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
2 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Repo: Cara menghidupkan semula rakan sepasukan
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Cara mendapatkan biji gergasi
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara menggunakan echarts dalam vue Cara menggunakan echarts dalam vue May 09, 2024 pm 04:24 PM

Menggunakan ECharts dalam Vue memudahkan untuk menambahkan keupayaan visualisasi data pada aplikasi anda. Langkah khusus termasuk: memasang pakej ECharts dan Vue ECharts, memperkenalkan ECharts, mencipta komponen carta, mengkonfigurasi pilihan, menggunakan komponen carta, menjadikan carta responsif kepada data Vue, menambah ciri interaktif dan menggunakan penggunaan lanjutan.

Peranan lalai eksport dalam vue Peranan lalai eksport dalam vue May 09, 2024 pm 06:48 PM

Soalan: Apakah peranan lalai eksport dalam Vue? Penerangan terperinci: eksport lalai mentakrifkan eksport lalai komponen. Apabila mengimport, komponen diimport secara automatik. Permudahkan proses import, tingkatkan kejelasan dan cegah konflik. Biasa digunakan untuk mengeksport komponen individu, menggunakan kedua-dua eksport bernama dan lalai, dan mendaftarkan komponen global.

Cara menggunakan fungsi peta dalam vue Cara menggunakan fungsi peta dalam vue May 09, 2024 pm 06:54 PM

Fungsi peta Vue.js ialah fungsi tertib tinggi terbina dalam yang mencipta tatasusunan baharu di mana setiap elemen ialah hasil yang diubah bagi setiap elemen dalam tatasusunan asal. Sintaks ialah map(callbackFn), di mana callbackFn menerima setiap elemen dalam tatasusunan sebagai argumen pertama, secara pilihan indeks sebagai argumen kedua, dan mengembalikan nilai. Fungsi peta tidak mengubah tatasusunan asal.

Perbezaan antara acara dan $event dalam vue Perbezaan antara acara dan $event dalam vue May 08, 2024 pm 04:42 PM

Dalam Vue.js, acara ialah peristiwa JavaScript asli yang dicetuskan oleh penyemak imbas, manakala $event ialah objek peristiwa abstrak khusus Vue yang digunakan dalam komponen Vue. Secara amnya lebih mudah untuk menggunakan $event kerana ia diformat dan dipertingkatkan untuk menyokong pengikatan data. Gunakan acara apabila anda perlu mengakses kefungsian khusus objek acara asli.

Perbezaan antara eksport dan eksport lalai dalam vue Perbezaan antara eksport dan eksport lalai dalam vue May 08, 2024 pm 05:27 PM

Terdapat dua cara untuk mengeksport modul dalam Vue.js: eksport dan eksport lalai. eksport digunakan untuk mengeksport entiti bernama dan memerlukan penggunaan pendakap kerinting lalai eksport digunakan untuk mengeksport entiti lalai dan tidak memerlukan pendakap kerinting. Apabila mengimport, entiti yang dieksport melalui eksport perlu menggunakan nama mereka, manakala entiti yang dieksport secara lalai eksport boleh digunakan secara tersirat. Adalah disyorkan untuk menggunakan lalai eksport untuk modul yang perlu diimport beberapa kali dan menggunakan eksport untuk modul yang hanya dieksport sekali.

Peranan onmounted dalam vue Peranan onmounted dalam vue May 09, 2024 pm 02:51 PM

onMounted ialah cangkuk kitaran hayat pemasangan komponen dalam Vue Fungsinya adalah untuk melaksanakan operasi pemulaan selepas komponen dipasang pada DOM, seperti mendapatkan rujukan kepada elemen DOM, menetapkan data, menghantar permintaan HTTP, mendaftarkan pendengar acara, dsb. Ia hanya dipanggil sekali apabila komponen dipasang Jika anda perlu melakukan operasi selepas komponen dikemas kini atau sebelum ia dimusnahkan, anda boleh menggunakan cangkuk kitar hayat yang lain.

Apakah cangkuk dalam vue Apakah cangkuk dalam vue May 09, 2024 pm 06:33 PM

Cangkuk Vue ialah fungsi panggil balik yang melakukan tindakan pada peristiwa tertentu atau peringkat kitaran hayat. Ia termasuk cangkuk kitaran hayat (seperti beforeCreate, mounted, beforeDestroy), cangkuk pengendalian acara (seperti klik, input, keydown) dan cangkuk tersuai. Cangkuk meningkatkan kawalan komponen, bertindak balas kepada kitaran hayat komponen, mengendalikan interaksi pengguna dan meningkatkan kebolehgunaan semula komponen. Untuk menggunakan cangkuk, hanya tentukan fungsi cangkuk, laksanakan logik dan kembalikan nilai pilihan.

Apakah senario yang boleh digunakan untuk pengubah suai peristiwa dalam vue? Apakah senario yang boleh digunakan untuk pengubah suai peristiwa dalam vue? May 09, 2024 pm 02:33 PM

Pengubah suai acara Vue.js digunakan untuk menambah gelagat tertentu, termasuk: menghalang gelagat lalai (.prevent) menghentikan acara menggelegak (.stop) acara sekali (.sekali) menangkap acara (.capture) mendengar acara pasif (.pasif) Suai pengubah suai (.self)Pengubah suai kunci (.key)

See all articles