springboot+websocket实现在线聊天(代码片段)

代码界小菜鸟 代码界小菜鸟     2023-03-01     523

关键词:

一、后端

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 事件

事件事件处理程序描述
openSocket.onopen连接建立时触发
messageSocket.onmessage客户端接受服务端数据时触发
errorSocket.onerror通信发生错误时触发
closeSocket.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 = se

java项目:在线聊天及聊天室系统(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加入相关静态资源文... 查看详情