current position:Home>Springboot + Vue to realize online chat (general version)
Springboot + Vue to realize online chat (general version)
2022-04-29 20:46:31【Programmer Qingge】
Just a few simple steps , You can realize online chat room !
Integration steps :
Back end Springboot
Springboot add to Pom rely on :
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
Remember to refresh after adding Maven, Lead the bag in .
stay common Catalog add Websocket To configure :
New this 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 {
/** * Into a ServerEndpointExporter, The Bean Will automatically register to use @ServerEndpoint Annotated with websocket endpoint */
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
newly build component Folder
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 service */
@ServerEndpoint(value = "/imserver/{username}")
@Component
public class WebSocketServer {
private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
/** * Record the current number of online connections */
public static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();
/** * Connection establishment method called successfully */
@OnOpen
public void onOpen(Session session, @PathParam("username") String username) {
sessionMap.put(username, session);
log.info(" New users have joined ,username={}, The current online population is :{}", 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)); // Send messages to all clients in the background
}
/** * Connection closes the called method */
@OnClose
public void onClose(Session session, @PathParam("username") String username) {
sessionMap.remove(username);
log.info(" There is a connection closed , remove username={} Users of session, The current online population is :{}", username, sessionMap.size());
}
/** * Method called upon receipt of a client message * The background receives the message sent by the client * onMessage It's a relay station for messages * Accept Browser side socket.send Sent by json data * @param message The message sent by the client */
@OnMessage
public void onMessage(String message, Session session, @PathParam("username") String username) {
log.info(" The server receives the user username={} The news of :{}", username, message);
JSONObject obj = JSONUtil.parseObj(message);
String toUsername = obj.getStr("to"); // to Indicates to which user , such as admin
String text = obj.getStr("text"); // Text of the message sent hello
// {"to": "admin", "text": " Chat text "}
Session toSession = sessionMap.get(toUsername); // according to to User name to get session, Re pass session Send message text
if (toSession != null) {
// Server side Assemble the message again , The assembled message contains the sender and the text content sent
// {"from": "zhang", "text": "hello"}
JSONObject jsonObject = new JSONObject();
jsonObject.set("from", username); // from yes zhang
jsonObject.set("text", text); // text Same as above text
this.sendMessage(jsonObject.toString(), toSession);
log.info(" Send to user username={}, news :{}", toUsername, jsonObject.toString());
} else {
log.info(" fail in send , User not found username={} Of session", toUsername);
}
}
@OnError
public void onError(Session session, Throwable error) {
log.error(" An error occurred ");
error.printStackTrace();
}
/** * The server sends a message to the client */
private void sendMessage(String message, Session toSession) {
try {
log.info(" Server to client [{}] Send a message {}", toSession.getId(), message);
toSession.getBasicRemote().sendText(message);
} catch (Exception e) {
log.error(" The server failed to send a message to the client ", e);
}
}
/** * The server sends messages to all clients */
private void sendAllMessage(String message) {
try {
for (Session session : sessionMap.values()) {
log.info(" Server to client [{}] Send a message {}", session.getId(), message);
session.getBasicRemote().sendText(message);
}
} catch (Exception e) {
log.error(" The server failed to send a message to the client ", e);
}
}
}
thus , The back-end code is integrated , After integration , Remember to restart your Springboot project
front end Vue
hold Im.vue Add to your Vue Inside the directory , direct copy Just go
<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"> Online users <span style="font-size: 12px">( Click the chat bubble to start chatting )</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 The chat room ({
{ 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"> send out </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: " Please choose a chat object "}) return; } if (!this.text) {
this.$message({
type: 'warning', message: " Please enter the content "}) } else {
if (typeof (WebSocket) == "undefined") {
console.log(" Your browser does not support it WebSocket"); } else {
console.log(" Your browser supports WebSocket"); // Assemble messages to be sent json // {"from": "zhang", "to": "admin", "text": " Chat text "} let message = {
from: this.user.username, to: this.chatUser, text: this.text} socket.send(JSON.stringify(message)); // Will be assembled json Send it to the server , Forward by the server this.messages.push({
user: this.user.username, text: this.text}) // Build message content , My message this.createContent(null, this.user.username, this.text) this.text = ''; } } }, createContent(remoteUser, nowUser, text) {
// This method is used to put json The chat message data is converted into html Of . let html // Current user message if (nowUser) {
// nowUser Indicates whether to display chat messages sent by the current user , Green bubble 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 Represents a remote user chat message , Blue bubbles 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(" Your browser does not support it WebSocket"); } else {
console.log(" Your browser supports WebSocket"); let socketUrl = "ws://localhost:9090/imserver/" + username; if (socket != null) {
socket.close(); socket = null; } // To start a websocket service socket = new WebSocket(socketUrl); // Open event socket.onopen = function () {
console.log("websocket Already opened "); }; // The browser receives messages , Get the text message sent from the server socket.onmessage = function (msg) {
console.log(" Receive the data ====" + msg.data) let data = JSON.parse(msg.data) // Yes, I received json Data analysis , Something like that : {"users": [{"username": "zhang"},{ "username": "admin"}]} if (data.users) {
// Get online personnel information _this.users = data.users.filter(user => user.username !== username) // Get all the user information of the current connection , And exclude yourself , I won't appear on my chat list } else {
// If it is sent from the server json data It doesn't contain users This key, So what's sent is the chat text json data // // {"from": "zhang", "text": "hello"} if (data.from === _this.chatUser) {
_this.messages.push(data) // Build message content _this.createContent(data.from, null, data.text) } } }; // Closing event socket.onclose = function () {
console.log("websocket closed "); }; // An error event occurred socket.onerror = function () {
console.log("websocket Something went wrong "); } } } } } </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>
Add a route :
{
path: 'im',
name: 'Im',
component: () => import("@/views/Im"),
},
Or use sql:
INSERT INTO `online-chat`.`sys_menu`(`id`, `name`, `path`, `icon`, `description`, `pid`, `page_path`, `sort_num`) VALUES (11, ' The chat room ', '/im', 'el-icon-chat-dot-square', NULL, NULL, 'Im', 999);
Configuration menu ( Optional , Or you can assign the menu directly , It depends on the framework you use ):
<el-menu-item index="/im"> <i class="el-icon-chat-dot-round"></i> The chat room </el-menu-item>
Okay , front end Vue The code ends here .
start-up Vue, Then test it :
Be careful , You need to turn on 2 A window or 2 A browser to test !
Then click the chat bubble , To receive and send messages .
Code integration considerations
front end Vue Get the user is using sessionStorage Of , If you use localStorage Access user information , Then you have to open 2 Only one browser can work properly , Bear in mind !
copyright notice
author[Programmer Qingge],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/04/202204292046265621.html
The sidebar is recommended
- Talking about nodejs server
- Node. js&lt; I & gt—— Encounter node and repl usage
- Vue basic API: calculation attribute + filter + listener
- 1-stm32 + mn316 (nb-iot) remote upgrade OTA (self built Internet of things platform) - STM32 uses HTTP to download program files and upgrade programs through mn316 (MCU program rotation check and update)
- Vue Axios response interception
- vue3 ref
- How does Vue transfer the data from the parent component to the child component intact?
- The back-end interface developed by springboot in idea and the Vue front-end developed by vscode. How to integrate Vue code into springboot?
- Fried cold rice series 4: scope and closure in JavaScript
- Typescript type compatibility learning
guess what you like
Summary of bugs encountered in front-end development
Chrome developer tool: performance analysis using web panel
Collation of common semantic elements and global attributes in HTML
Life cycle in Vue
5.1 fear of traffic jam? With a budget of less than 100000, these cars with adaptive cruise make it easy for you to travel
Docker compose deploy nginx configure SSL
The content of element type “mapper“ must match “(cache-ref|cache|resultMap*|parameterMap*|sql*|inse
-CSS-
Vue uses two-way binding to implement the user registration page
Is Infiniti qx60 worth less than 400000 yuan? It depends on the discount
Random recommended
- "Element Fangjian: first heart version" public beta welfare release, go to the great God app to receive red envelopes and prizes
- What is the role of webpack cli in webpack packaging
- Vue3 configuration method using Axios
- How to configure Google reverse proxy on nginx server
- Volume comparison between Vue and react
- What are the three ways to define components in react
- How to install and configure the blogging program Typecho on the nginx server
- How to configure load balancing for TCP in nginx server
- How to configure nginx server under Windows system
- How to configure AB to do stress testing for nginx server
- Analysis of location configuration in nginx server
- How to integrate Linux and redmine into the redmine system
- How to build the production environment of nginx + PHP with PHP FPM
- How to optimize the performance of nginx supporting SSL
- How to configure nginx server to prevent flood attack
- [Axios learning] basic use of Axios
- [Axios learning] Axios request mode, concurrent request, global configuration, instance and interceptor
- Use the virtual queue implemented by list to view the first element of the queue in Python without taking it out
- This dependency was not found and to install it, you can run: NPM install score JS
- Front end serial communication
- leedcode. 203 remove linked list elements
- Dialogue with Liu Dayong, information director of Jiuyang shares: key elements of enterprise digital intelligence transformation
- JQuery gets the method summary of parent element, child element and brother element
- Web Security: analysis of DOM XSS vulnerability source code of jquery
- The sales volume of Genesys in China is 283, less than 300, and the domestic sales volume is dismal
- This beast was blessed with skills to test drive the DHT version of Harvard beast
- Bootstrap and jQuery implement tree structure
- Fried cold rice series 5: recursion in JavaScript?
- 2022 open source summer | serverless devs accompany you to "become stronger"
- How to create a high-performance full screen red envelope rain
- Detailed process of spring boot free HTTPS project configuration!
- Create a simple vue3 project
- How to create a simple react project
- Vue custom text background
- Front end HTML
- leetcode:462. Minimum number of moves to make array elements equal II [sort + find the middle]
- City selection (provincial and urban cascade) plug-in v-distpicker component details and a full set of usage
- How to use js to achieve such a drag and zoom effect
- Quick report ~ node JS 18 coming! Let's see what's new
- Easily manage projects using Vue UI graphical interface