关键词:
一、后端
1.在Springboot项目的pom.xml中添加依赖
<!--websocket协议-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.3</version>
</dependency>
2.要想使用WebSocket配置config配置类
package com.websocket.config;
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
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter()
return new ServerEndpointExporter();
3.新建component问价夹,下方新建WebSocketServer核心代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FJo3rH5s-1675864417091)(C:\\Users\\86155\\Desktop\\websocket实现聊天室\\image-20230208193030259.png)]
package com.websocket.component;
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<>();
/**
* 连接建立成功调用的方法
*/
@OnOpen
public 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)); // 后台发送消息给所有的客户端
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session, @PathParam("username") String username)
sessionMap.remove(username);
log.info("有一连接关闭,移除username=的用户session, 当前在线人数为:", username, sessionMap.size());
/**
* 收到客户端消息后调用的方法
* 后台收到客户端发送过来的消息
* onMessage 是一个消息的中转站
* 接受 浏览器端 socket.send 发送过来的 json数据
* @param message 客户端发送过来的消息
*/
@OnMessage
public 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表示发送给哪个用户,比如 admin
String 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 是 zhang
jsonObject.set("text", text); // text 同上面的text
this.sendMessage(jsonObject.toString(), toSession);
log.info("发送给用户username=,消息:", toUsername, jsonObject.toString());
else
log.info("发送失败,未找到用户username=的session", toUsername);
@OnError
public 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.如果有拦截就放开拦截
我没有设置拦截,全部都是放开的
二、Websocket
1.Websocket 属性
属性 | 描述 |
---|---|
Socket.readyState | 只读属性 ready State 表示连接状态,可以是以下值: 0 - 表示连接尚未建立 1 - 表示连接已经建立,可以进行通信。 2 - 表示连接正在关闭 3 - 表示连接已经关闭或者连接不能打开 |
Socket.buffereAmount | 只读属性 buffereAmount 已被 send()放入队列中等待传输,但是还没有发出的utf-8文本字节数 |
2.WebSocket 事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接受服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
3.WebSocket 方法—一下是 WebSocket对象的相关方法,假定我们使用了以上代码创建Socket 对象
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
三、前端
<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 = sejava项目:在线聊天及聊天室系统(java+springboot+freemark+websocket+mysql)(代码片段)
springboot+freemark+websocket+MySQL实现的Javaweb在线聊天系统,主要实现的功能有:前台:1、用户注册、登录。2、搜索用户添加好友。3、查看好友申请列表,同意或拒绝好友请求。4、成为好友后单人一对一聊天... 查看详情
javaspringboot整合websocket
【Java】SpringBoot整合WebSocketWebSocket简介WebSocket是一种协议,用于实现客户端和服务器之间的双向通信。它可以在单个TCP连接上提供全双工通信,避免了HTTP协议中的请求-响应模式,从而实现更高效的数据交换。WebSocket协议最初由HT... 查看详情
springboot集成websocket,轻松实现信息推送!
在一次项目开发中,使用到了Netty网络应用框架,以及MQTT进行消息数据的收发,这其中需要后台来将获取到的消息主动推送给前端,于是就使用到了MQTT,特此记录一下。一、什么是websocket?WebSocket协议是基于TCP的一种新的网络... 查看详情
微服务-springboot+websocket在线聊天室
一.引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>二.注入ServerEndpointExporter编写一个WebSoc 查看详情
基于websocket协议的研究demo
1、日志推送 websocket在线测试WebSocket在线测试工具物联网http://www.websocket-test.com/2、Springboot+vue的聊天:Springboot+websocket+vue的web聊天项目https://gitee.com/xzlmk/spring_boot_vue_chat 3、实时通信 4、基于C#net4.5实现最 查看详情
springboot基于websocket进行推送
参考技术A客户端发起http请求,请求Netty服务器进行WebSocket连接,服务器接收后请求后进行注册信道并登记客户端IP地址,如此一来就建立了WebSocket通讯连接。上面的论述可以得出,我们可以比较Http和WebSocket两者之间的关系和区... 查看详情
springboot实现websocket(代码片段)
...一个websocket应该怎么实现,这里采用的是更加方便的Springboot的方式,如果项目中没有使用springboot框架,也是可以 查看详情
springboot实现websocket(代码片段)
...一个websocket应该怎么实现,这里采用的是更加方便的Springboot的方式,如果项目中没有使用springboot框架,也是可以 查看详情
springboot实现websocket(代码片段)
...一个websocket应该怎么实现,这里采用的是更加方便的Springboot的方式,如果项目中没有使用springboot框架,也是可以 查看详情
springboot整合websocket
...t:在浏览器和服务器之间建立tcp连接,实现全双工通信??springboot使用websocket有两种方式,一种是实现简单的websocket,另外一种是实现STOMP协议。这一篇实现简单的webso 查看详情
springboot+websocket学习(代码片段)
Springboot+WebSocket聊天室项目WebSocket介绍WebSocket的特点webSocket协议客户端(浏览器)实现websocket对象websocket事件WebSocket方法服务端实现服务端如何接受客户端发送过来的数据呢?服务端如何推送数据给客户端呢?基于WebSocket的网页聊... 查看详情
使用springboot+layim+websocket实现webim
使用springboot+layim+websocket实现webim 小白技术社 项目介绍采用springboot和layim构建webim,使用websocket作为通讯协议,目前已经能够正常聊天,并没有对好友的操作进行实现,查找和加好友没有实现,有需... 查看详情
springboot2系列教程(十六)|整合websocket实现广播
前言如题,今天介绍的是SpringBoot整合WebSocket实现广播消息。什么是WebSocket?WebSocket为浏览器和服务器提供了双工异步通信的功能,即浏览器可以向服务器发送信息,反之也成立。WebSocket是通过一个socket来实现双工异步通信能力... 查看详情
springboot-websocket实现及原理
本文章包括websocket面试相关问题以及springboot如何整合webSocket。参考文档https://blog.csdn.net/prayallforyou/article/details/53737901、https://www.cnblogs.com/bianzy/p/5822426.html webSocket是HTML5的一种新协议,它实现了服务端与客户端的全双工通信,... 查看详情
推荐一个.netcore开发的websocket群聊私聊的开源项目
...子 ,一起打卡交流学习。今天给大家推荐一个使用Websocket协议实现的、高性能即时聊天组件,可用于群聊、好友聊天、游戏直播等场景。项目简介这是一个基于.NetCore开发的、简单、高性能的通讯组件,支持点对点... 查看详情
springboot实现websocket单聊
一、创建项目并导入依赖??<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> & 查看详情
springboot实现websocket群聊
一、创建项目并导入依赖??<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <gr 查看详情
springboot——springboot集成websocket实现简单的多人聊天室(代码片段)
文章目录:1.什么是WebSocket?2.Java中的WebSocketAPI2.1WebSocket开发中的相关注解及API方法2.2前端技术对WebSocket的支持3.多人聊天室的实现源码3.1pom文件中添加相关依赖2.2在核心配置文件中配置视图解析器2.3加入相关静态资源文... 查看详情