您好,欢迎访问一九零五行业门户网

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

一、数据库搭建很简单的一个user表,加两个用户admin和wskh
二、后端搭建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 */@configurationpublic 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}")@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("/**") .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("发送成功"); }}
至此,后端部分大体配置完毕。
三、前端搭建本文使用vue-admin-template-master模板进行聊天室的前端搭建
3.1 自定义文件websocket.js将下面文件放在api文件夹下
//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中全局引入websocketimport '@/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搭建简易网页聊天室的详细内容。
其它类似信息

推荐信息