springboot+vue集成websocket实现聊天功能

1、添加pom依赖

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

2、创建一个config文件夹,在config文件夹中创建一个 WebSocketConfig.java 类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig {/*** 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

3、新建一个 component 文件夹,并且在 component 文件夹中新建  WebSocketServer.java 类

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
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.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @author websocket服务*/
@ServerEndpoint(value = "/imserver/{username}")
@Component
public class WebSocketServer {private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);/*** 记录当前在线连接数*/public static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("username") String username) {sessionMap.put(username, session);log.info("有新用户加入,username={}, 当前在线人数为:{}", username, sessionMap.size());JSONObject result = new JSONObject();JSONArray array = new JSONArray();result.set("users", array);for (Object key : sessionMap.keySet()) {JSONObject jsonObject = new JSONObject();jsonObject.set("username", key);// {"username", "zhang", "username": "admin"}array.add(jsonObject);}
//        {"users": [{"username": "zhang"},{ "username": "admin"}]}sendAllMessage(JSONUtil.toJsonStr(result));  // 后台发送消息给所有的客户端}/*** 连接关闭调用的方法*/@OnClosepublic void onClose(Session session, @PathParam("username") String username) {sessionMap.remove(username);log.info("有一连接关闭,移除username={}的用户session, 当前在线人数为:{}", username, sessionMap.size());}/*** 收到客户端消息后调用的方法* 后台收到客户端发送过来的消息* onMessage 是一个消息的中转站* 接受 浏览器端 socket.send 发送过来的 json数据* @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session, @PathParam("username") String username) {log.info("服务端收到用户username={}的消息:{}", username, message);JSONObject obj = JSONUtil.parseObj(message);String toUsername = obj.getStr("to"); // to表示发送给哪个用户,比如 adminString text = obj.getStr("text"); // 发送的消息文本  hello// {"to": "admin", "text": "聊天文本"}Session toSession = sessionMap.get(toUsername); // 根据 to用户名来获取 session,再通过session发送消息文本if (toSession != null) {// 服务器端 再把消息组装一下,组装后的消息包含发送人和发送的文本内容// {"from": "zhang", "text": "hello"}JSONObject jsonObject = new JSONObject();jsonObject.set("from", username);  // from 是 zhangjsonObject.set("text", text);  // text 同上面的textthis.sendMessage(jsonObject.toString(), toSession);log.info("发送给用户username={},消息:{}", toUsername, jsonObject.toString());} else {log.info("发送失败,未找到用户username={}的session", toUsername);}}@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误");error.printStackTrace();}/*** 服务端发送消息给客户端*/private void sendMessage(String message, Session toSession) {try {log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);toSession.getBasicRemote().sendText(message);} catch (Exception e) {log.error("服务端发送消息给客户端失败", e);}}/*** 服务端发送消息给所有客户端*/private void sendAllMessage(String message) {try {for (Session session : sessionMap.values()) {log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);session.getBasicRemote().sendText(message);}} catch (Exception e) {log.error("服务端发送消息给客户端失败", e);}}
}

 4、在你的token拦截里,放行该接口

 5、新建Vue页面,Im.vue

<template><div style="padding: 10px; margin-bottom: 50px"><el-row><el-col :span="4"><el-card style="width: 300px; height: 300px; color: #333"><div style="padding-bottom: 10px; border-bottom: 1px solid #ccc">在线用户<span style="font-size: 12px">(点击聊天气泡开始聊天)</span></div><div style="padding: 10px 0" v-for="user in users" :key="user.username"><span>{{ user.username }}</span><i class="el-icon-chat-dot-round" style="margin-left: 10px; font-size: 16px; cursor: pointer"@click="chatUser = user.username"></i><span style="font-size: 12px;color: limegreen; margin-left: 5px" v-if="user.username === chatUser">chatting...</span></div></el-card></el-col><el-col :span="20"><div style="width: 800px; margin: 0 auto; background-color: white;border-radius: 5px; box-shadow: 0 0 10px #ccc"><div style="text-align: center; line-height: 50px;">Web聊天室({{ chatUser }})</div><div style="height: 350px; overflow:auto; border-top: 1px solid #ccc" v-html="content"></div><div style="height: 200px"><textarea v-model="text" style="height: 160px; width: 100%; padding: 20px; border: none; border-top: 1px solid #ccc;border-bottom: 1px solid #ccc; outline: none"></textarea><div style="text-align: right; padding-right: 10px"><el-button type="primary" size="mini" @click="send">发送</el-button></div></div></div></el-col></el-row></div>
</template><script>import request from "@/utils/request";let socket;export default {name: "Im",data() {return {circleUrl: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',user: {},isCollapse: false,users: [],chatUser: '',text: "",messages: [],content: ''}},created() {this.init()},methods: {send() {if (!this.chatUser) {this.$message({type: 'warning', message: "请选择聊天对象"})return;}if (!this.text) {this.$message({type: 'warning', message: "请输入内容"})} else {if (typeof (WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");} else {console.log("您的浏览器支持WebSocket");// 组装待发送的消息 json// {"from": "zhang", "to": "admin", "text": "聊天文本"}let message = {from: this.user.username, to: this.chatUser, text: this.text}socket.send(JSON.stringify(message));  // 将组装好的json发送给服务端,由服务端进行转发this.messages.push({user: this.user.username, text: this.text})// 构建消息内容,本人消息this.createContent(null, this.user.username, this.text)this.text = '';}}},createContent(remoteUser, nowUser, text) {  // 这个方法是用来将 json的聊天消息数据转换成 html的。let html// 当前用户消息if (nowUser) { // nowUser 表示是否显示当前用户发送的聊天消息,绿色气泡html = "<div class=\"el-row\" style=\"padding: 5px 0\">\n" +"  <div class=\"el-col el-col-22\" style=\"text-align: right; padding-right: 10px\">\n" +"    <div class=\"tip left\">" + text + "</div>\n" +"  </div>\n" +"  <div class=\"el-col el-col-2\">\n" +"  <span class=\"el-avatar el-avatar--circle\" style=\"height: 40px; width: 40px; line-height: 40px;\">\n" +"    <img src=\"https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png\" style=\"object-fit: cover;\">\n" +"  </span>\n" +"  </div>\n" +"</div>";} else if (remoteUser) {   // remoteUser表示远程用户聊天消息,蓝色的气泡html = "<div class=\"el-row\" style=\"padding: 5px 0\">\n" +"  <div class=\"el-col el-col-2\" style=\"text-align: right\">\n" +"  <span class=\"el-avatar el-avatar--circle\" style=\"height: 40px; width: 40px; line-height: 40px;\">\n" +"    <img src=\"https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png\" style=\"object-fit: cover;\">\n" +"  </span>\n" +"  </div>\n" +"  <div class=\"el-col el-col-22\" style=\"text-align: left; padding-left: 10px\">\n" +"    <div class=\"tip right\">" + text + "</div>\n" +"  </div>\n" +"</div>";}console.log(html)this.content += html;},init() {this.user = sessionStorage.getItem("user") ? JSON.parse(sessionStorage.getItem("user")) : {}let username = this.user.username;let _this = this;if (typeof (WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");} else {console.log("您的浏览器支持WebSocket");let socketUrl = "ws://localhost:9090/imserver/" + username;if (socket != null) {socket.close();socket = null;}// 开启一个websocket服务socket = new WebSocket(socketUrl);//打开事件socket.onopen = function () {console.log("websocket已打开");};//  浏览器端收消息,获得从服务端发送过来的文本消息socket.onmessage = function (msg) {console.log("收到数据====" + msg.data)let data = JSON.parse(msg.data)  // 对收到的json数据进行解析, 类似这样的: {"users": [{"username": "zhang"},{ "username": "admin"}]}if (data.users) {  // 获取在线人员信息_this.users = data.users.filter(user => user.username !== username)  // 获取当前连接的所有用户信息,并且排除自身,自己不会出现在自己的聊天列表里} else {// 如果服务器端发送过来的json数据 不包含 users 这个key,那么发送过来的就是聊天文本json数据//  // {"from": "zhang", "text": "hello"}if (data.from === _this.chatUser) {_this.messages.push(data)// 构建消息内容_this.createContent(data.from, null, data.text)}}};//关闭事件socket.onclose = function () {console.log("websocket已关闭");};//发生了错误事件socket.onerror = function () {console.log("websocket发生了错误");}}}}
}</script><style>
.tip {color: white;text-align: center;border-radius: 10px;font-family: sans-serif;padding: 10px;width:auto;display:inline-block !important;display:inline;
}.right {background-color: deepskyblue;
}
.left {background-color: forestgreen;
}
</style>

最后设置路由就好啦 

{path: 'im',name: 'Im',component: () => import("@/views/Im"),
},

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22567.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

广州租房房价分析

利用八爪鱼爬链家网上广州市租房房源数据&#xff0c;网址为https://gz.lianjia.com/zufang/&#xff0c;爬取字段为价格、租赁方式、房型、楼层、面积、朝向、地铁、小区、位置、经度、纬度等&#xff0c;保存到E盘数据分析课程设计文件夹下&#xff0c;存为“gz_zufang.csv”…

房价数据分析

文章目录 一、数据预处理1、删除多余列2、缺失值、异常值处理 二、 数据探索分析1、DistanceKM与房价关系2、14岁及以下比重与房价关系3、自驾实际值与房价关系4、65岁及以上比重与房价关系5、人口占比与房价关系 三、机器学习预测房价1、模型选择2、模型调参 四、总结 一、数据…

北京二手房房价分析(建模篇)

数据科学俱乐部 中国数据科学家社区 本篇将继续上一篇数据分析用Python分析北京二手房房价之后进行数据挖掘建模预测&#xff0c;这两部分构成了一个简单的完整项目。结合两篇文章通过数据分析和挖掘的方法可以达到二手房屋价格预测的效果。 下面从特征工程开始讲述。 特征工程…

我国主要城市2023年房价数据

房价是一个城市发展程度的重要体现&#xff0c;一个城市的房价越高通常代表这个城市越发达&#xff0c;对于人口的吸引力越大&#xff01;因此&#xff0c;房价数据是我们在各项城市研究中都非常常用的数据&#xff01; 本次我们为大家带来的是我国主要城市的房价数据&#xf…

分析天津市房价的空间因素影响

所有代码与解析 # -*- coding: utf-8 -*- """ Created on Thu Mar 4 16:23:30 2021author: 89344 """import numpy as np import pandas as pd import matplotlib.pyplot as plt import warnings warnings.filterwarnings(ignore) from bokeh.…

Python爬取天津房价并进行可视化

Python爬取天津房价并进行可视化 步骤代码 步骤 1.爬取网页信息 2.解析网页信息&#xff0c;获取需要的数据&#xff0c;存入CSV文件中 3.读取CSV文件&#xff0c;对数据进行处理&#xff0c;包括剔除异常值&#xff0c;空值等&#xff0c;进行可视化 代码 import requests …

房价概况:2013年2月26日天津各区县房价一览

2013年2月26日全市新建商品房交易373套、面积37502.8平方米&#xff0c;平均价格每平方米10504元。其中&#xff0c;住宅335套、面积34159.8平方米&#xff0c;平均价格每平方米9844元。二手住宅交易275套、面积22696.8平方米&#xff0c;平均价格每平方米8579元。

Spring实战----Taco Cloud(墨西哥煎玉米卷在线订购系统)

记录一下根据《Spring实战&#xff08;第五版&#xff09;》(人民邮电出版社)所学习的过程 目录 项目初始化 开发WEB应用 使用数据库 使用Spring Data JPA进行持久化数据 使用Spring Security保护Spring 自定义用户验证 项目初始化 New一个Project&#xff0c;选择Sprin…

C/C++字符串

一.C风格的字符串 1. char a[6] { h,e,l,l,o,\0 }; printf("%s", a);//hello#include<iostream> #include<string> using namespace std; int main() {char a[6] { h,e,l,l,o,\0 };char b[5] { h,e,l,l,o};//空间至少大一位留出\0位置char c[6] { h,e…

Qt输入窗口部件编程(一) QComboBox和QFontComboBox

文章目录 前言1、 Qt常用的输入窗口控件2、QFontComboBox 和 QComboBox控件编程2.1 控件简介2.1.1 QComboBox组合框2.1.2 QFontComboBox字体组合框 2.2 例程功能设计2.3 例程执行效果2.4 生成项目2.5 代码编辑2.5.1 修改项目文件_qcombobox.pro2.5.2 修改 main.cpp2.5.3 修改 w…

Xmind8 乱码问题解决(查看文件字体并下载安装相应字体)

每台电脑引起Xmind软件出现乱码的原因也不一样&#xff0c;本文仅适用于解决字体缺少或者字体版本不对而引发的乱码问题。每台电脑缺少的字体包也不一样&#xff0c;要通过“工具”-》“提取样式”菜单&#xff0c;具体分析自己的Xmind文件需要什么字体&#xff0c;然后搜索对应…

idea主题 插件 乱码 快捷键

idea样式网站 http://www.easycolor.cc/ http://www.riaway.com/ idea 乱码情况 中文乱码问题分类&#xff1a; 1.编码普通中文乱码 2.properties文件中文乱码 3.console控制台中文乱码 4.搜索框中文乱码 5.svn注释中文乱码 解决方法&#xff1a; 1、编码普通中文乱码 ①s…

基于声学模型共享的零资源韩语识别系统

声学模型共享方法是极低资源小语种语音识别一种解决方案&#xff0c;能够实现不需要任何语音数据的语音识别。本文介绍清华大学语音与音频技术实验室的零资源韩语语音系统&#xff0c;其在不使用任何韩语语音数据的情况下&#xff0c;在Zeroth韩语数据集上的测试CER达到了27.33…

韩语在线翻译图片识别_图片怎么转表格excel

图片转表格excel&#xff0c;快来免费用 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 相信大部分小伙伴选择拍图识字 是因为强大的ocr识别功能 图片文字一键提取导出 但是&#xff0c;有多少人知道 拍图识字还可以成为你的私人翻译&#xff01;1 多语言转换 拍图识字首页点击拍照/…

韩译中难吗,如何做好韩语翻译

我们知道&#xff0c;韩语是韩国的官方语言&#xff0c;由于长期和中国文化的接触&#xff0c;历史上曾用汉字标记&#xff0c;并且将汉语融入其词汇&#xff0c;基于这一特点&#xff0c;韩译中难吗&#xff0c;如何做好韩语翻译? 据了解&#xff0c;中韩文化交流的历史可以追…

韩语在线翻译图片识别_3个OCR文字识别工具,最后一个许多人都不知道!

在日常生活和工作中,经常有需要录入一张图片或实物内容的文字信息的时候,对于少量内容,你或许可以轻松完成。可是一旦内容多,而你打字速度又不快的情况下,那可真的是一件非常枯燥又费力的事情。 而一般遇到这种情况,大家就可以利用OCR文字识别工具,只需简单对着物体拍张…

韩语在线翻译图片识别_如何用扫描全能王将图片转成文字?

扫描君有个写材料的朋友&#xff0c;每次需要摘录书或宣传册里的内容&#xff0c;他总是一个字一个字地敲&#xff0c;效率不高&#xff0c;还容易出错&#xff0c;自己也很痛苦&#xff01;&#xff01; 扫描君也有这样的亲身体会&#xff1a; 在微博、朋友圈里看到一些图片或…

韩语翻译拍照怎么弄?分享几款拍照翻译软件

拍照翻译软件是一种基于人工智能技术开发的翻译工具&#xff0c;它可以通过拍照识别文字&#xff0c;然后将文字翻译成大家选择的语言。这种翻译方式比传统的输入文字翻译更加方便快捷&#xff0c;无需手动输入文字&#xff0c;提高了翻译的效率、准确性&#xff0c;也提供更好…

yandex的“Search queries” report(搜索查询报告)

上一篇提到了我们查询访客关键词的入口&#xff0c;需要从“搜索查询”报告中点击进入&#xff0c;那么我们好好的来了解一下其中数据的具体含义吧~ 首先&#xff1a;该报告包含来自投放您的广告的搜索平台的用户查询&#xff0c;包括与您的关键字在语义上匹配的搜索查询。这句…

韩语识别_韩语文字识别_韩语图片识别 - 云+社区 - 腾讯云

广告关闭 腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元! 购买预付费包更加优惠 识别 小时语音不到 元 每月赠送免费额度最大程度降低客户成本 效果好 字准率 处于业界领先水平 与微信王者荣耀的语音转文字使用一套服…