検索
ホームページJava&#&チュートリアルWebSocket + SpringBoot + Vue を使用して簡単な Web チャット ルームを構築する方法

1. データベースのセットアップ

非常に単純なユーザー テーブルに、admin と wskh の 2 人のユーザーを追加します

WebSocket + SpringBoot + Vue を使用して簡単な Web チャット ルームを構築する方法

2. バックエンドのセットアップ

2.1 主要な依存関係の紹介
<dependency>            
    <groupId>org.springframework.boot</groupId>            
    <artifactId>spring-boot-starter-websocket</artifactId>       
</dependency>
2.2 WebSocket 構成クラス

WebSocketConfig の機能は、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(); 
    }
}

WebSocketServer は、メッセージ イベントの送信、接続の確立などのいくつかのイベントを書き込みますイベント、接続終了イベントなど。

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;
    }
}
2.3 クロスドメインの構成
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);
    }

}
2.4 メッセージ送信用の制御クラス
/**
 * @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("发送成功");
    }
}

この時点で、バックエンド部分は次のとおりです。一般的に構成されています。

3. フロントエンドの構築

この記事では、vue-admin-template-master テンプレートを使用してチャット ルームのフロントエンドを構築します

3.1 カスタム ファイル WebSocket .js

次のファイルを api フォルダーに配置します

WebSocket + SpringBoot + Vue を使用して簡単な Web チャット ルームを構築する方法##

//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

3.2 main.js
import &#39;@/utils/websocket&#39; // 全局引入 WebSocket 通讯组件
3.3 に WebSocket をグローバルに導入します
##3.3 WebSocket を宣言します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>

3.4 チャット ルームのインターフェイス.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>
3.5 最終的な効果
2 つの異なるブラウザを使用してログインします管理者アカウントにアクセスし、wskh アカウントでチャット テストを行うと、結果は次のようになります (管理者が左側にあります):

WebSocket + SpringBoot + Vue を使用して簡単な Web チャット ルームを構築する方法

以上がWebSocket + SpringBoot + Vue を使用して簡単な Web チャット ルームを構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、