文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室

2023-07-05 14:38

关注

这篇文章主要讲解了“怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室”吧!

一、数据库搭建

很简单的一个user表,加两个用户admin和wskh

怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室

二、后端搭建

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;@Configurationpublic class WebSocketConfig {         @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}")@Componentpublic 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;@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {    @Override    // 跨域配置    public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("@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("发送成功");    }}

至此,后端部分大体配置完毕。

三、前端搭建

本文使用vue-admin-template-master模板进行聊天室的前端搭建

3.1 自定义文件websocket.js

将下面文件放在api文件夹下

怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室

//websocket.jsimport Vue from 'vue'// 1、用于保存WebSocket 实例对象export const WebSocketHandle = undefined// 2、外部根据具体登录地址实例化WebSocket 然后回传保存WebSocketexport 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('收到消息:', msg)  // 2、如果外部回调函数未绑定 结束操作  if (!WebSocket.WebSocketOnMsgEvent_CallBack) {    console.log(WebSocket.WebSocketOnMsgEvent_CallBack)    return  }  // 3、调用外部函数  WebSocket.WebSocketOnMsgEvent_CallBack(msg)}// 4、全局存放外部页面绑定onmessage消息回调函数:注意使用的是varexport 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、全局绑定WebSocketVue.prototype.$WebSocket = WebSocket
3.2 main.js中全局引入websocket
import '@/utils/websocket' // 全局引入 WebSocket 通讯组件
3.3 App.vue中声明websocket对象

App.vue

<template>  <div id="app">    <router-view />  </div></template><script>  import {getInfo} from './api/login.js';  import {getToken} from './utils/auth.js'  export default {    name: 'App',    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('收到服务器消息:', msg.data)        console.log(msg)        let chatDiv = document.getElementById("chatDiv")        let newH3 = document.createElement("div")        if(msg.data.indexOf('openSuccess')>=0){// 忽略连接成功消息提示        }else{          if(msg.data.indexOf(this.userName)==0){            // 说明是自己发的消息,应该靠右边悬浮            newH3.innerHTML = "<div style='width:100%;text-align: right;'><h4 style=''>"+msg.data+"</h4></div>"          }else{            newH3.innerHTML = "<div style='width:100%;text-align: left;'><h4 style=''>"+msg.data+"</h4></div>"          }        }        chatDiv.appendChild(newH3)      },      // 1、WebSocket连接状态检测:      WebSocket_StatusCheck() {        if (!this.$WebSocket.WebSocketHandle || this.$WebSocket.WebSocketHandle.readyState !== 1) {          console.log('Websocket连接中断,尝试重新连接:')          this.WebSocketINI()        }      },      // 2、WebSocket初始化:      async WebSocketINI() {        // 1、浏览器是否支持WebSocket检测        if (!('WebSocket' in window)) {          console.log('您的浏览器不支持WebSocket!')          return        }        let DEFAULT_URL = "ws://" + '127.0.0.1:8002' + '/websocket/' + 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('webcoket连接成功')        }        //6、连接失败提示        tmpWebsocket.onclose = function(e) {          console.log('webcoket连接关闭:', 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 '../../api/login.js';  import {getToken} from '../../utils/auth.js'  import msgApi from '../../api/msg.js'  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 最终效果

用两个不同的浏览器,分别登录admin账号和wskh账号进行聊天测试,效果如下(左边为admin):

怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室

感谢各位的阅读,以上就是“怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室”的内容了,经过本文的学习后,相信大家对怎么使用WebSocket+SpringBoot+Vue搭建简易网页聊天室这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯