从 0 开始实现一个网页聊天室 (小型项目)(上)

简介: 从 0 开始实现一个网页聊天室 (小型项目)

实现功能

  1. 用户注册和登录
  2. 好友列表展示
  3. 会话列表展示: 显示当前正在进行哪些会话 (单聊 / 群聊) , 选中好友列表中的某个好友, 会生成对应的会话
  4. 实时通信, A给B发送消息, B的聊天界面 / 会话界面能立刻显示新的消息


TODO:

  1. 添加好友功能
  2. 用户头像显示
  3. 传输图片 / 表情包
  4. 历史消息搜索
  5. 消息撤回

相关技术


网络通信: WebSocket

Spring + SpringBoot + SpringMVC + MyBatis

HTML + CSS + JS

数据库设计

项目的基本框架

前端页面

注册和登录页面

聊天界面

后端代码

实体类

User

本类表示一个用户的信息, 对应数据库的 user 表

@Data
public class User {

    private int userId;
    private String username = "";
    private String password = "";

    public User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}

Friend

使用一个 Friend 对象表示一个好友

// 使用一个 Friend 对象表示一个好友, 对应数据库的 friend 表
@Data
public class Friend {
    private int friendId;
    private String friendName;

    public Friend() {
    }

    public Friend(int friendId, String friendName) {
        this.friendId = friendId;
        this.friendName = friendName;
    }
}

Message

本类表示一条消息的相关信息, 对应数据库的表 message + 字段: fromname

(没有 postTime 是因为: 在查询的时候就是一次性查出所有的时间, 按照时间结果排序后返回, 我们这里就不需要再获取时间了)

// 本类表示一条消息的相关信息
// (没有 postTime 是因为: 在查询的时候就是一次性查出所有的时间, 按照时间结果排序后返回, 我们这里就不需要再获取时间了)
@Data
public class Message {
    private Integer messageId;
    private int fromId;
    private String fromName;
    private int sessionId;
    private String content;

    public Message() {
    }

    public Message( int fromId, String fromName, int sessionId, String content) {
        this.fromId = fromId;
        this.fromName = fromName;
        this.sessionId = sessionId;
        this.content = content;
    }
}

MessageSession

使用该类表示一个会话, 对应数据库的 message_session + message_session_user

// 使用该类表示一个会话
@Data
public class MessageSession {
    private int sessionId;
    private List<Friend> friends;
    private String lastMessage;
}

MessageSessionUserItem

该类对象表示 message_session_user 表里的一个记录

// 该类对象表示 message_session_user 表里的一个记录
@Data
public class MessageSessionUserItem {
    private int sessionId;
    private int userId;

    public MessageSessionUserItem() {
    }

    public MessageSessionUserItem(int sessionId, int userId) {
        this.sessionId = sessionId;
        this.userId = userId;
    }
}

MessageRequest

WebSocket 请求

自定义格式, 用于网络通信中接受请求

// WebSocket请求
@Data
public class MessageRequest {
    private String type = "message";
    private int sessionId;
    private String content;
}

MessageResponse

WebSocket 响应

自定义格式, 用于网络通信中返回响应

// WebSocket响应
@Data
public class MessageResponse {
    private String type = "message";
    private int fromId;
    private String fromName;
    private int sessionId;
    private String content;

    public MessageResponse() {
    }

    public MessageResponse(int fromId, String fromName, int sessionId, String content) {
        this.fromId = fromId;
        this.fromName = fromName;
        this.sessionId = sessionId;
        this.content = content;
    }
}

数据库

FriendMapper

用户好友的相关操作

@Mapper
public interface FriendMapper {
    // 查询用户好友列表
    List<Friend> selectFriendList(@Param("userId") int userId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.java_chatroom.model.FriendMapper">

    <select id="selectFriendList" resultType="com.example.java_chatroom.model.Friend">
        select userId as friendId, username as friendName
        from user
        where userId in
        (select friendId from friend where userId = #{userId})
    </select>
</mapper>

MessageMapper

消息的相关操作

@Mapper
public interface MessageMapper {

    // 获取指定会话的最后一条消息
    String getLastMessageBySessionId(@Param("sessionId") int sessionId);

    // 获取指定会话的历史消息 (限制100条)
    List<Message> getMessagesBySessionId(@Param("sessionId") int sessionId);

    // 插入一条消息到数据库表中
    void add(@Param("message") Message message);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.java_chatroom.model.MessageMapper">

    <select id="getLastMessageBySessionId" resultType="java.lang.String">
        select content from message
        where sessionId = #{sessionId}
        order by postTime desc
        limit 1
    </select>

    <select id="getMessagesBySessionId" resultType="com.example.java_chatroom.model.Message">
        select
            messageId, sessionId, fromId, content, username as fromName
        from
            message, user
        where
            sessionId = #{sessionId}
            and fromId = userId
        order by
            postTime desc
        limit 100 offset 0
    </select>

    <insert id="add">
        insert into message values(null, #{message.fromId}, #{message.sessionId}, #{message.content}, now());
    </insert>
</mapper>

MessageSessionMapper

会话的相关操作

@Mapper
public interface MessageSessionMapper {
    // 1.根据 userId 获取到该用户在哪些会话中存在, 返回结果是一组 sessionId.
    List<Integer> getSessionIdsByUserId(@Param("userId") int userId);

    // 2. 根据 sessionId 查询这个会话包含哪些用户(刨除掉最初的 user)
    List<Friend> getFriendsBySessionId(@Param("sessionId") int sessionId,@Param("selfUserId") int selfUserId);

    // 3. 新增会话记录, 返回会话 id
    int addMessageSession(@Param("messageSession") MessageSession messageSession);

    // 4.给 message_session_user 表新增对应记录
    int addMessageSessionUser(@Param("messageSessionUserItem") MessageSessionUserItem messageSessionUserItem);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.java_chatroom.model.MessageSessionMapper">

    <select id="getSessionIdsByUserId" resultType="java.lang.Integer">
        select sessionId from message_session
        where sessionId in
            ( select sessionId from message_session_user
             where userId = #{userId} )
        order by lastTime desc
    </select>

    <select id="getFriendsBySessionId" resultType="com.example.java_chatroom.model.Friend">
        select userId as friendId, username as friendName
        from user
        where userId in
            ( select userId from message_session_user
                where sessionId = #{sessionId}
                and userId != #{selfUserId} )
    </select>

    <insert id="addMessageSession" useGeneratedKeys="true" keyProperty="messageSession.sessionId">
        insert into message_session values(null, now())
    </insert>

    <insert id="addMessageSessionUser">
        insert into message_session_user values(
            #{messageSessionUserItem.sessionId},
            #{messageSessionUserItem.userId}
        )
    </insert>
</mapper>

从 0 开始实现一个网页聊天室 (小型项目)(下):https://developer.aliyun.com/article/1520799

目录
相关文章
|
存储 并行计算 安全
我们自己的芯片指令集架构——龙芯架构简介
我们自己的芯片指令集架构——龙芯架构简介
2631 6
|
网络协议 网络架构
内网IP 外网IP 网卡 路由器通信过程(全)
       这几天上了计算机网络的课,对于老师讲的内容也是懵懵懂懂,一个慌神就没跟上,啥ip 啥NAT一脸蒙蔽。课后oogle补了点东西算是大致有了点了解,不过网上的总结都是零零散散而且点到即止。
5337 0
|
JSON 前端开发 安全
【Java Web项目】基于WebSocket的Web聊天室
本项目的名称为Web聊天室,即类QQ群组聊天,多个用户可以在同一个群组收发消息进行聊天
【Java Web项目】基于WebSocket的Web聊天室
|
8月前
|
存储 人工智能 前端开发
Botgroup.chat:超有趣的开源 AI 聊天室!多个 AI 在线互怼,一键搭建你的专属 AI 社群
Botgroup.chat 是一款基于 React 和 Cloudflare Pages 的开源 AI 聊天应用,支持多个 AI 角色同时参与对话,提供类似群聊的交互体验。
1966 28
WK
|
C++ 开发者
QPushButton
QPushButton 是 Qt 框架中的一个控件,用于创建可按压的按钮。它可以作为独立控件或嵌入其他窗口中,常用于添加按钮并绑定点击信号。支持设置文本、图标、快捷键等属性,可通过样式表自定义外观。示例代码展示了如何创建带有图标的按钮并连接点击信号。
WK
396 1
|
前端开发 Java API
Swagger接口文档 —— 手把手教学,全方位超详细小白能看懂,百分百能用Java版
本文提供了一份详细的Swagger接口文档生成工具的使用教程,包括了导入依赖、配置类设置、资源映射、拦截器配置、Swagger注解使用、生成接口文档、在线调试页面访问以及如何设置全局参数(如token),旨在帮助Java开发者快速上手Swagger。
8386 0
Swagger接口文档 —— 手把手教学,全方位超详细小白能看懂,百分百能用Java版
|
缓存 算法 Linux
Linux内核中的内存管理机制深度剖析####
【10月更文挑战第28天】 本文深入探讨了Linux操作系统的心脏——内核,聚焦其内存管理机制的奥秘。不同于传统摘要的概述方式,本文将以一次虚拟的内存分配请求为引子,逐步揭开Linux如何高效、安全地管理着从微小嵌入式设备到庞大数据中心数以千计程序的内存需求。通过这段旅程,读者将直观感受到Linux内存管理的精妙设计与强大能力,以及它是如何在复杂多变的环境中保持系统稳定与性能优化的。 ####
253 0
|
前端开发 JavaScript
从 0 开始实现一个网页聊天室 (小型项目)(下)
从 0 开始实现一个网页聊天室 (小型项目)
161 16
|
域名解析 弹性计算 监控
用阿里云服务器搭建论坛教程
```markdown 1. 购买阿里云ECS实例 2. 配置域名解析至服务器IP 3. 安装Nginx/Apache,部署论坛文件 4. 安装MySQL,创建数据库和用户 5. 选择论坛程序(如Discuz!),完成安装配置 6. 自定义论坛参数,设置功能 7. 可选:启用SSL证书增强安全性 8. 定期备份数据,监控服务器性能 确保更新维护,顺利搭建安全论坛!求助阿里云客服或文档以获取支持。 ```
447 0
|
前端开发 容器
CSS【详解】对齐 (含文本垂直对齐,文本水平对齐、单行文本垂直居中、多行文本垂直居中、6 种方案块级元素水平垂直居中 、7 种方案图片水平垂直居中、文本自适应对齐、图标和文本对齐,图片和文本对齐等)
CSS【详解】对齐 (含文本垂直对齐,文本水平对齐、单行文本垂直居中、多行文本垂直居中、6 种方案块级元素水平垂直居中 、7 种方案图片水平垂直居中、文本自适应对齐、图标和文本对齐,图片和文本对齐等)
872 0