You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

聊天应用私有群组功能异常:加入后崩溃,离开后无法发消息

多人聊天应用群组功能崩溃及消息发送问题修复

问题根源

  • 加入群组后崩溃:Group.remove_member方法在成员未存在于群组时调用set.remove()会触发KeyError,导致线程崩溃;同时消息发送逻辑未区分"群组内"和"全局"场景。
  • 离开群组后无法发消息:离开群组后代码未恢复全局广播逻辑,且客户端未同步更新状态提示。

修复方案

1. 修复Group类的移除成员方法(避免崩溃)

修改server.py中的Group类remove_member方法,先检查成员是否存在再执行删除:

def remove_member(self, client_handler):
    with groups_lock:
        if client_handler in self.members:
            self.members.remove(client_handler)

2. 调整消息发送逻辑(区分群组/全局)

在server.py的消息处理循环中,替换原全局广播代码,根据用户是否在群组内选择发送目标:

# 替换原有的全局广播代码段
if not message or message == "/exit":
    break
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
broadcast_message = f"[{current_time}] {self.username}: {message}"

if self.group:
    # 处于群组内,仅发送给群成员
    self.group.send_to_all(broadcast_message, self)
else:
    # 未加入群组,全局广播
    with clients_lock:
        for usr, client in clients.items():
            if usr != self.username:
                client.send(broadcast_message.encode('utf-8'))

3. 客户端显示当前房间(用户名旁标注群组)

修改client.py,新增群组状态跟踪,并在输入提示中展示:

def start_client(host, port):
    try:
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client_socket.connect((host, port))
        message_lock = threading.Lock()
        current_group = None  # 新增:跟踪当前群组状态
    except ConnectionRefusedError as e:
        if e.errno == 111:
            print("Connection refused")
        else:
            print(f"An unknown error occurred {e}")
        return

    # 保留原有获取用户名的代码...

    # 修改监听服务器消息的函数,同步群组状态
    def listen_to_server():
        nonlocal username, current_group
        while True:
            data = client_socket.recv(1024).decode('utf-8')
            if not data:
                break
            with message_lock:
                # 更新群组状态
                if "Joined group '" in data:
                    current_group = data.split("Joined group '")[1].rstrip("'.")
                elif "Left group '" in data:
                    current_group = None
                # 更新用户名
                if "Username changed to " in data:
                    username = data.split("Username changed to ")[1].rstrip(".")
                # 构建带群组的提示文本
                prompt = f"{username}"
                if current_group:
                    prompt += f" [{current_group}]"
                prompt += f":{Fore.YELLOW} Enter your message: {Style.RESET_ALL}"
                print(f"{Fore.GREEN}\n{data}\n{Style.RESET_ALL}{prompt}", end='')

    threading.Thread(target=listen_to_server, daemon=True).start()

    # 修改输入循环的提示文本
    while True:
        try:
            prompt = f"{username}"
            if current_group:
                prompt += f" [{current_group}]"
            prompt += f": {Fore.YELLOW}Enter your message: {Style.RESET_ALL}"
            print(prompt, end='')
            message = input()
            # 保留原有消息发送逻辑...

4. 优化群组命令的参数处理(可选)

避免用户输入不带密码的群组命令时出现分割错误,修改server.py中/creategroup和/joingroup的处理:

# 修改/creategroup处理
if message.startswith("/creategroup "):
    parts = message.split(maxsplit=2)
    if len(parts) < 2:
        self.client_socket.send("Usage: /creategroup [group_name] [password (optional)]".encode('utf-8'))
        continue
    group_name = parts[1]
    password = parts[2] if len(parts) > 2 else ""
    hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest() if password else None
    # 保留原有群组创建逻辑...

# 修改/joingroup处理
if message.startswith("/joingroup "):
    parts = message.split(maxsplit=2)
    if len(parts) < 2:
        self.client_socket.send("Usage: /joingroup [group_name] [password (if required)]".encode('utf-8'))
        continue
    group_name = parts[1]
    password = parts[2] if len(parts) > 2 else ""
    hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest() if password else None
    # 保留原有群组加入逻辑...

内容的提问来源于stack exchange,提问作者user12328867

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:30:57