SpringBoot与webSocket实现在线聊天室——实现私聊+群聊+聊天记录保存

包结构图:代码部分:实体类:UserMessage.java 定义实体类与数据库连接,存储聊天记录package com.example.springboot_websocket.bean;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.util.Date;/** * @author Admin
摘要由CSDN通过智能技术生成

SpringBoot与webSocket实现在线聊天室——实现私聊+群聊+聊天记录保存

引用参考:原文章地址:https://blog.csdn.net/qq_41463655/article/details/92410518

在此基础上实现对聊天记录的保存。

代码地址:链接:https://pan.baidu.com/s/1IJFZDa4S_DF08773sKJWeA 提取码:jkui
思路:新建一个实体类用于保存聊天记录,在消息发送时,设置对象的各个值然后保存到数据库中。
实现步骤:
  1. 实体类: 新建实体类UserMessage,根据需要设置对象的字段,如:发送者、接收者、信息内容、发送时间等。
  2. mapper层:写UserMessageMapper接口,继承BaseMapper(我使用的是mybatis-plus,也可以使用其他方法)。
  3. service层:UserMessageService继承IService,service实现类UserMessageServiceImpl继承ServiceImpl<UserMessageMapper, UserMessage> 实现UserMessageService。
  4. controller层:在UserMessageController中的onMessage方法中,将前端传过来的json解析为字段,新建UserMessage对象message1,设置message1对象的各个值,通过消息接收者类型的判断,确实数据库中接收者的值如何设置,然后将UserMessage对象保存到数据库中。
此时,聊天记录保存到数据库时,是一条一条进行保存,为了减少对数据库频繁的操作,在UserMessageController类中定义一个静态的集合MessageList用来暂时保存聊天记录,并且设置MessageList集合的长度为一个固定值不可变,目的是为了实现将聊天记录保存到集合中,当集合的长度等于设定的值时,批量将聊天记录保存到数据库中。
  1. 所以将聊天记录保存到数据库前,先将聊天记录保存到集合MessageList中,判断集合的长度,如果集合的长度等于设定的值,将集合中的数据批量保存到数据库中,然后清空集合,为下一次保存聊天记录做准备。
我在实现保存聊天记录功能时遇到的问题:
  1. 代码没有错,群聊、私聊都可以实现,但是无法保存聊天记录,错:设置的表名与数据库没有对应好。
  2. 保存聊天记录的集合一定要设置为全局,如果是在方法中新建集合,那么聊天记录保存的并不是同一个集合,导致集合的长度永远无法达到设定的值,无法批量保存,导致数据保存失败。
  3. 当聊天页面关闭时,聊天记录的数据就会丢失,为什么不在UserMessageController中的onClose方法中判断在关闭聊天框前,集合中是否有聊天记录,如果有则进行保存??因为设置的集合为全局变量,就算是关闭了聊天页面,聊天记录也会暂时保存到集合中,并不会丢失。
效果展示图:

页面展示
实现聊天
数据库信息

完整代码实现如下:
包结构图:

websocket

代码部分:
webSocket配置类:WebSocketConfig.java
package com.example.springboot_websocket.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @author Administrator
 */

@Configuration
@Component
public class WebSocketConfig {
   

    /**
     * 服务器节点
     *
     * 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
   
        return new ServerEndpointExporter();
    }
}
实体类:UserMessage.java 定义实体类与数据库连接,存储聊天记录
package com.example.springboot_websocket.bean;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author Administrator
 */

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserMessage {
   

    /**
     * 消息发送者
     */
    private String username;

    /**
     * 聊天文本
     */
    private String message;

    /**
     * 消息接受者
     */
    private String tousername;

    /**
     * 发送时间
     */
    private Date createtime;
}
mapper层:UserMessageMapper.java
package com.example.springboot_websocket.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot_websocket.bean.UserMessage;
import org.apache.ibatis.annotations.Mapper;

/**
 * extends BaseMapper<T>:继承接口即可实现基本的CRUD方法
 * <p>
 * 1.如果自定义的mapper继承了mybatis-plus的BaseMapper时,xxxMapper.xml中不可以包含insert方法,因为在BaseMapper中存在该方法
 * 2.如果对应的xxxMapper.xml中包含insert方法,那么就会执行xxxMapper.xml中的方法,相当于重写BaseMapper中的insert方法;
 * 如果xxxMapper.xml中没有insert方法,默认使用BaseMapper中的方法
 * 3.注意:BaseMapper<T>中的泛型对应相应的实体类
 */

/**
 * @author Administrator
 */

@Mapper
public interface UserMessageMapper extends BaseMapper<UserMessage> {
   

}
service层:UserMessageService.java
package com.example.springboot_websocket.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.springboot_websocket.bean.UserMessage;

/**
 * @author Administrator
 */
public interface UserMessageService extends IService<UserMessage> {
   

}
service层:UserMessageServiceImpl .java
package com.example.springboot_websocket.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot_websocket.bean.UserMessage;
import com.example.springboot_websocket.mapper.UserMessageMapper;
import org.springframework.stereotype.Service;

/**
 * @author Administrator
 */

@Service
public class UserMessageServiceImpl extends ServiceImpl<UserMessageMapper, UserMessage> implements UserMessageService {
   

}
controller层:UserMessageController.java
package com.example.springboot_websocket.controller;

import com.alibaba.fastjson.JSON;
import com.example.springboot_websocket.bean.UserMessage;
import com.example.springboot_websocket.service.UserMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket类
 *
 * @ServerEndpoint: socket链接地址
 */

/**
 * @author Administrator
 */

@ServerEndpoint("/websocket/{username}")
@Controller
@Component
public class UserMessageController {
   

    /**
     * 设置一次性存储数据的list的长度为固定值,每当list的长度达到固定值时,向数据库存储一次
     */
    private static final Integer LIST_SIZE = 3;

    /**
     * 设置在线人数为静态变量
     */
    public static int onlineNumber = 0;

    private static UserMessageService userMessageService;

    /**
     * 新建list集合存储数据
     */
    private static ArrayList<UserMessage> MessageList = new ArrayList<>();

    /**
     * map(username,websocket)作为对象添加到集合中
     */
    private static Map<String, UserMessageController> clients = new ConcurrentHashMap<String, UserMessageController>();

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * session会话
     */
    private Session session;
    /**
     * 用户名称
     */
    private String username;

    public static synchronized int getOnlineCount() {
   
        return onlineNumber;
    }

    @Autowired
    public void setOgLocationService(UserMessageService userMessageService) {
   
        UserMessageController.userMessageService = userMessageService;
    }

    /**
     * 进入聊天室 --> 项目中读取用户信息获取用户名
     */
    @RequestMapping
  • 21
    点赞
  • 188
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
### 回答1: Spring Boot实现私信功能可以采用以下步骤: 1. 在数据库中建立私信表,存储私信的发送者、接收者、内容等信息。 2. 在 Spring Boot 中配置数据库连接,使用 JPA 或者 MyBatis 等框架来操作数据库。 3. 在后端代码中编写私信相关接口,如发送私信、查看私信列表等。 4. 在前端代码中实现私信功能,如私信对话框、私信列表等。 5. 实现私信消息的推送,可以使用 websocket 或者消息队列等技术。 6. 设置私信权限控制,在接口中进行验证。 需要注意的是,这只是一个大体的步骤,实际实现过程中还需要根据具体需求进行调整。 ### 回答2: Spring Boot是一个用于构建Java应用程序的开源框架。要实现私信功能,可以参考以下步骤: 1. 创建消息实体类:创建一个Java类,作为私信的消息实体。该类应该包含发送者、接收者、消息内容等属性。 2. 创建消息存储库:使用Spring Data JPA或其他持久化技术创建一个消息存储库。该存储库应该包含查找和保存消息的方法。 3. 创建发送消息的API:使用Spring MVC创建一个发送消息的API接口。该接口应该接受发送者、接收者和消息内容作为参数,并将消息保存到消息存储库中。 4. 创建查看消息的API:使用Spring MVC创建一个查看消息的API接口。该接口应该接受用户ID作为参数,并从消息存储库中查找与该用户相关的所有消息。 5. 创建WebSocket连接:使用Spring WebSocket创建一个WebSocket连接,以便实时传输私信消息。当消息存储库中有新的消息时,将其推送到WebSocket连接的订阅者。 6. 创建前端界面:创建一个前端界面,让用户可以发送、查看私信消息。可以使用HTML、CSS和JavaScript技术来实现。 7. 配置Spring Boot应用程序:配置Spring Boot应用程序以启用WebSocket和相关的URL路由。 8. 测试私信功能:使用测试工具或编写单元测试来测试私信功能的正确性和性能。 通过上述步骤,可以在Spring Boot应用程序中实现私信功能。当用户发送私信时,消息将保存到消息存储库,并且可以通过API接口或前端界面查看私信消息。另外,通过WebSocket连接,用户能够实时接收私信消息的推送。 ### 回答3: Spring Boot实现私信功能的一种方式是使用消息队列和WebSocket。 首先,我们可以使用消息队列来实现私信的消息传递。比如使用ActiveMQ或者RabbitMQ作为消息队列,用户可以将私信消息发送到队列中,然后接收者可以从队列中订阅并接收消息。 其次,我们可以使用WebSocket实现私信的实时通信功能。WebSocket是一种在浏览器和服务器之间进行双向通信的协议,通过使用WebSocket,用户可以实时地接收到私信消息。 在Spring Boot中,我们可以使用Spring WebSocket模块来实现私信功能。首先,我们需要配置WebSocket相关的类和处理器。然后,在用户发送私信时,我们可以通过WebSocket发送消息到接收者。接收者收到消息后,可以在前端页面上实时展示。 为了保证私信的安全性,我们还可以添加用户身份认证和授权的机制。比如,在使用WebSocket进行通信时,可以在建立连接时对用户进行身份验证,并限制用户只能向特定的用户发送私信。 另外,我们还可以使用数据库来存储私信记录。每当用户发送或接收一条私信时,我们可以将其保存在数据库中,以供用户随时查看和管理。 总的来说,通过使用消息队列和WebSocket,结合用户身份认证和数据库存储,我们可以在Spring Boot实现私信功能。这种实现方式可以使私信消息实时、安全,并且提供了便捷的管理功能。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值