web聊天室项目开发过程及重难点整理

本文详述了一个web聊天室的开发过程,包括需求分析、业务背景、前后端接口设计、功能实现原理及代码展示。重点讨论了WebSocket在消息推送中的应用,以及如何处理session会话、ajax异步请求、数据库操作等技术点。项目亮点在于使用了阻塞队列和双重校验锁来优化系统性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、需求分析

1.登录:同一个浏览器,即使多个标签页,保持相同的session。
2.对应消息频道可以收发消息,不同的消息频道不能收发。
3.历史记录查看,新登陆用户可以查看退出登陆后的消息

二、业务背景

1.张三要发消息给李四

实现
1.客户端点到点发消息
2.服务端转发消息(本项目方法)

在这里插入图片描述

使用http协议是不可以的因为
服务端的IP是开放在公网的,所有人都能访问
客户端的IP是不开放的

2.WebSocket实现消息推送流程

一.客户端和服务器端建立连接,只能客户发起请求,双方建立链接。

//客户端js代码
websocket = new WebSocket("ws://localhost:8080/java_chatroom/test/1");

1.1双方建立连接(双方通知打开连接的回调函数执行)
1.2客户端建立连接回调

//连接成功建立的回调方法
      websocket.onopen = function(event){
   
          setMessageInnerHTML("open");
      }

1.3服务端建立连接回调,同时建立长连接Session

@OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
   
        this.userId = userId;
        System.out.println("打开连接: " + userId);
    }

二、双方的通信都是全双工,客户端和服务端都可以主动收发消息
2.1客户端发送消息

//发送消息
      function send(){
   
          var message = document.getElementById('text').value;
          websocket.send(message);
      }

2.2服务端发送消息

@OnMessage
    public void onMessage(String message, Session session) throws IOException {
   
        System.out.println("收到消息! " + userId + ": " + message);
        session.getBasicRemote().sendText(message);
    }

建立连接以后,就会有的会话对象,只要有sesiion引用就可以发消息,区别于Servlet的session

三、双方接收消息:被动接受(事件驱动的异步回调)
3.1:客户端接收消息

	//接收到消息的回调方法
      websocket.onmessage = function(event){
   
          setMessageInnerHTML(event.data);
      }

3.2:服务端接收消息

	@OnMessage
    public void onMessage(String message, Session session) throws IOException {
   
        System.out.println("收到消息! " + userId + ": " + message);
        //session.getBasicRemote().sendText(message);
    }

三、前后端接口和数据库系统设计

1.用户相关的接口

1.注册

请求:
POST /register
{
   
    name: xxx,
    password: xxx,
    nickName: "蔡徐坤",
    signature: "我擅长唱跳rap篮球", }
响应: 
HTTP/1.1 200 OK
{
   
    ok: 1,
    reason: xxx
}

2.登录 输入账号密码,点击登录按钮,调用的接口

请求:
POST /login
{
   
    name: xxx,
    password: xxx
}
响应: 
HTTP/1.1 200 OK
{
   
    ok: 1,
    reason: xxx,
    userId: xxx,
    name: xxx,
    nickName: xxx,
    signature: xxx
}

3.检查登陆状态 页面初始化,调用的接口

请求:
GET /login
响应:
响应: 
HTTP/1.1 200 OK
{
   
    ok: 1,
    userId: xxx,
    name: xxx,
    nickName: xxx,
    signature: xxx
}

注销

请求:
GET /logout
响应:
HTTP/1.1 200 OK
{
   
    ok: 1,
    reason: xxx
}

2.频道相关接口

查找频道

请求:
GET /channel
响应:
HTTP/1.1 200 OK
[
 {
   
        channelId: 1,
        channelName: xxx
   },
   {
   
        channelId: 2,
        channelName: xxx
   }
]

3.数据库表的设计

user表

create table user (
				   userId int primary key auto_increment,
                   name varchar(50) unique,
                   password varchar(50),
                   nickName varchar(50),   -- 昵称
                   iconPath varchar(2048), -- 头像路径
                   signature varchar(100),
                   lastLogout DateTime -- 上次登录时间
); -- 个性签名

频道表

create table channel (channelId int primary key auto_increment,
                      channelName varchar(50)
);
insert into channel values(null, '体坛赛事');
insert into channel values(null, '娱乐八卦');
insert into channel values(null, '时事新闻');
insert into channel values(null, '午夜情感');

信息表

create table message (messageId int primary key auto_increment,
                      userId int, -- 谁发的
                      channelId int, -- 发到哪个频道中
                      content text, -- 消息内容
                      sendTime DateTime default now()    -- 发送时间
);

insert into message values (null, 1, 1, 'hehe1', now());
insert into message values (null, 1, 1, 'hehe2', now());
insert into message values (null, 1, 1, 'hehe3', now());

四、功能交互实现原理及代码展示

在这里插入图片描述

1.输入url访问主页

2.调用检查登陆状态接口

在这里插入图片描述

2.1参数ok:true时显示登录信息

在这里插入图片描述

3.响应ok:false不包含用户信息显示未登录界面

在这里插入图片描述

4.点击登录按钮显示登录框

在这里插入图片描述

5.输入账号密码,点击登录按钮调用login接口,创建session

请求:
POST /login
{
   
    name: xxx,
    password: xxx
}
响应: 
HTTP/1.1 200 OK
{
   
    ok: 1,
    reason: xxx,
    userId: xxx,
    name: xxx,
    nickName: xxx,
    signature: xxx
}

在这里插入图片描述

6.参数ok:true表示登陆成功跳转至频道列表页面

在这里插入图片描述

7.查找频道信息初始化websocket

			app.getChannels();
            app.initWebSocket();
7.1查找频道接口
请求:
GET /channel
响应:
HTTP/1.1 200 OK
[
 {
   
        channelId: 1,
        channelName: xxx
   },
   {
   
        channelId: 2,
        channelName: xxx
   }
]
7.2调用初始化websocket方法,筛选频道
 		if('WebSocket' in window){
   
          this.websocket = new WebSocket("ws://localhost:8080/java_chatroom/message/" + this.user.userId);
          console.log("link success")
        }else{
   
          alert('Not support websocket')
        }
        //连接发生错误的回调方法
        this.websocket.onerror = function () {
   
          alert("连接发生错误!");
        };

        //连接成功建立的回调方法
        this.websocket.onopen = function (event) {
   
          console.log("连接建立成功");
        }
        //接收到消息的回调方法
        this.websocket.onmessage = function (event) {
   
        let message = JSON.parse(event.data);
          app.messages.push(message);
          //筛选频道
        app.curChannelMessages = app.messages.filter((message, i) => {
   
            if (message.channelId ==
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值