聊天室设计思路

聊天场景

  1. 所有人都在同一个群中聊天
  2. 只有一个人发送消息,在线的所有人都能收到(核心)
  3. 针对离线的人(注册过,但是没有登录的人),等他再次登录,补发没有看到过的历史消息
  4. 首次注册的人,看不到之前的消息

深入场景

  1. 我们需要一个在线用户管理机制(记录当前所有在线用户信息),可以同时动态的、正确的维护该信息
    (1)有人登录,添加到在线列表
    (2)有人登出,踢出在线列表
  2. 一个人发送消息的数据流转流程:
    (1)前端获取用户要发布的消息
    (2)通过websocket,将消息推送给服务端
    (3)后端遍历所有当前在线用户,通过websocket挨个发送消息

库表信息
用户表:uid,username,nickname,password,上次登出时间(注册用户时,上次登陆时间记为null)
消息表:mid,uid,context,发送时间

聊天室主要结构

在这里插入图片描述

只要建立一个websocket链接,就会生成一个endpoint对象,用来维护在线用户信息
每发送一条消息,找到所有在线用户,把所有消息发出去;并且要经过messageDao层,把信息把存到mysql中
只要上线,就会把在线用户信息维护起来(记录当前在线用户情况),然后在messageDao层中查询所有历史消息,发送给上线的这个用户
下线,首先要在用户列表中删除掉该用户,然后把本次下线的时间记录在数据库中,然后在下次上线时才可以根据下线时间,以及查询到的历史消息时间,可以查询到它的历史消息

WebSocket中事件驱动的上如何做到处理
用户上线、用户下线、发送消息三种不同业务事件
onOpen、onClose、 onMessage 三种不同的websocket

  • 处理用户上线逻辑
    1. 判断上线的是哪个用户
    从HttpSession中获取当前登录用户的信息
    这个Session不是HttpSession
    这里的Sesion实际上值得是WebSocket Session
    2. 记录该用户到在线用户列表中(如果重复上线,把之前的踢下线)
    3. 查找历史信息并发送

  • 处理用户下线逻辑
    1. 记录当前用户下线时间
    当前用户从哪里获取?
    我们当前无法获取该信息,需提前保存该信息
    2. 从在线用户列表中踢出当前用户

  • 处理收到用户发来的消息的逻辑
    1. 记录消息
    是当前用户发的消息,发的内容是什么
    2. 把消息转发给所有在线用户

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计思路: 1. 服务器端建立一个监听socket,等待客户端的连接请求; 2. 当客户端连接请求到达时,服务器端接受请求,创建一个新的socket与客户端进行通信,并将其加入到一个socket列表中保存; 3. 客户端连接成功后,发送一个登录请求到服务器端,服务器端接收到请求后将客户端的信息加入到一个客户端列表中保存; 4. 当某个客户端发送消息时,服务器端接收到消息后,将消息转发给所有在线客户端; 5. 当某个客户端断开连接时,服务器端将其从客户端列表和socket列表中删除,并且通知其他客户端该用户已下线。 实现步骤: 1. 服务器端创建监听socket,等待客户端连接请求; 2. 客户端连接成功后,服务器端创建一个新的socket与客户端进行通信,并将其加入到一个socket列表中保存; 3. 客户端连接成功后,发送一个登录请求到服务器端,服务器端接收到请求后将客户端的信息加入到一个客户端列表中保存; 4. 当某个客户端发送消息时,服务器端接收到消息后,将消息转发给所有在线客户端; 5. 当某个客户端断开连接时,服务器端将其从客户端列表和socket列表中删除,并且通知其他客户端该用户已下线。 代码实现: 1. 服务器端 ```python import socket def server(): # 创建socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 server_socket.bind(('127.0.0.1', 8000)) # 监听端口 server_socket.listen(5) # 客户端列表 clients = [] # 循环等待客户端连接 while True: client_socket, client_addr = server_socket.accept() print(f'客户端{client_addr}连接成功!') # 将新客户端加入到客户端列表中 clients.append((client_socket, client_addr)) # 创建一个新线程,处理该客户端的消息 threading.Thread(target=handle_client, args=(client_socket, clients)).start() def handle_client(client_socket, clients): # 接收客户端发送的登录请求 username = client_socket.recv(1024).decode() # 将客户端信息加入到客户端列表中 clients.append((client_socket, username)) # 向所有在线客户端广播新用户加入的消息 broadcast(f'{username}已加入聊天!', clients) # 循环接收客户端发送的消息 while True: try: message = client_socket.recv(1024).decode() # 将消息转发给所有在线客户端 broadcast(f'{username}: {message}', clients) except: # 当客户端断开连接时,从客户端列表和socket列表中删除该客户端 clients.remove((client_socket, username)) broadcast(f'{username}已离开聊天!', clients) break def broadcast(message, clients): # 循环向所有在线客户端发送消息 for client in clients: client_socket = client[0] # 发送消息时,需要将消息转换为字节流 client_socket.send(message.encode()) if __name__ == '__main__': server() ``` 2. 客户端 ```python import socket import threading def client(): # 创建socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 client_socket.connect(('127.0.0.1', 8000)) # 发送登录请求 username = input('请输入您的用户名:') client_socket.send(username.encode()) # 创建一个新线程,用于接收服务器发送的消息 threading.Thread(target=receive_message, args=(client_socket,)).start() # 循环发送消息 while True: message = input() client_socket.send(message.encode()) def receive_message(client_socket): while True: message = client_socket.recv(1024).decode() print(message) if __name__ == '__main__': client() ``` 以上代码实现了简单的TCP通信的多人聊天,但仅供参考,具体实现还需要考虑更多的细节问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值