You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.0 KiB

用户名策略

📋 用户名规则

唯一性要求

系统强制要求用户名唯一,不允许重复登录。

规则说明

  1. 每个用户名只能被一个连接使用

    • 如果用户名已被占用,新的登录请求将被拒绝
    • 系统会提示"用户名已被使用,请更换用户名"
  2. 用户名区分大小写

    • Alicealice 是不同的用户名
    • BobBOB 是不同的用户名
  3. 用户名长度限制

    • 最小长度1个字符
    • 最大长度20个字符
    • 不能为空
  4. 允许的字符

    • 中文字符
    • 英文字母
    • 数字
    • 特殊符号

🔒 实现机制

服务器端检查

WebSocket服务器

public synchronized boolean addClient(String username, WebSocketClient client) {
    // 检查用户名是否已存在
    if (clients.containsKey(username)) {
        System.out.println("用户名 " + username + " 已被使用,拒绝登录");
        return false;
    }
    
    clients.put(username, client);
    System.out.println("用户 " + username + " 已登录");
    broadcastUserList();
    return true;
}

TCP服务器

public synchronized boolean addClient(String username, ClientHandler handler) {
    // 检查用户名是否已存在
    if (clients.containsKey(username)) {
        System.out.println("用户名 " + username + " 已被使用,拒绝登录");
        return false;
    }
    
    clients.put(username, handler);
    System.out.println("用户 " + username + " 已登录");
    broadcastUserList();
    return true;
}

客户端处理

Web客户端

case 'LOGIN_SUCCESS':
    // 登录成功,显示聊天界面
    document.getElementById('loginModal').classList.add('hidden');
    document.getElementById('chatContainer').classList.remove('hidden');
    break;
    
case 'LOGIN_FAILED':
    // 登录失败,显示错误提示
    alert(message.content);
    ws.close();
    break;

📱 用户体验

登录流程

成功场景

1. 用户输入用户名 "Alice"
2. 点击登录
3. 连接WebSocket
4. 发送登录请求
5. 服务器检查用户名
6. 用户名可用 ✅
7. 返回 LOGIN_SUCCESS
8. 显示聊天界面

失败场景

1. 用户输入用户名 "Alice"
2. 点击登录
3. 连接WebSocket
4. 发送登录请求
5. 服务器检查用户名
6. 用户名已被使用 ❌
7. 返回 LOGIN_FAILED
8. 显示错误提示:"用户名已被使用,请更换用户名"
9. 关闭连接
10. 用户可以重新输入用户名

错误提示

Web客户端

弹窗提示:用户名已被使用,请更换用户名

命令行客户端:

[系统] 用户名已被使用,请更换用户名
连接已关闭

🔄 用户名释放

自动释放

用户名在以下情况下会被释放:

  1. 正常退出

    • 用户点击"退出"按钮
    • 发送LOGOUT消息
    • 服务器移除用户
  2. 连接断开

    • WebSocket连接关闭
    • TCP连接断开
    • 网络异常
  3. 超时断开

    • 长时间无响应
    • 心跳检测失败

释放流程

1. 检测到连接断开
2. 调用 removeClient(username)
3. 从在线用户列表中移除
4. 广播更新用户列表
5. 用户名可被其他人使用

🎯 最佳实践

推荐的用户名

好的用户名示例:

  • 张三
  • Alice
  • 用户001
  • 测试账号
  • Bob_2024

不推荐的用户名:

  • (空格)
  • "" (空字符串)
  • 过长的用户名超过20字符

测试建议

单用户测试

1. 打开浏览器
2. 访问 http://120.46.87.202:8080
3. 输入用户名 "TestUser1"
4. 登录成功

重复用户名测试

1. 打开第一个浏览器标签页
2. 输入用户名 "Alice",登录成功
3. 打开第二个浏览器标签页
4. 输入用户名 "Alice",登录失败
5. 看到提示:"用户名已被使用,请更换用户名"
6. 更换为 "Bob",登录成功

用户名释放测试

1. 用户 "Alice" 登录
2. 关闭 Alice 的浏览器标签页
3. 等待几秒
4. 重新打开浏览器
5. 再次使用 "Alice" 登录
6. 登录成功(用户名已释放)

🐛 故障排除

问题1明明没人用却提示用户名已被使用

可能原因:

  • 之前的连接未正常关闭
  • 服务器缓存未清理

解决方案:

  1. 等待30秒后重试
  2. 重启服务器
  3. 使用不同的用户名

问题2用户名释放不及时

可能原因:

  • 网络延迟
  • 服务器处理延迟

解决方案:

  1. 等待几秒后重试
  2. 检查服务器日志
  3. 确认连接已完全关闭

问题3无法登录

检查清单:

  • 用户名是否为空?
  • 用户名是否超过20字符
  • 是否有其他人正在使用该用户名?
  • 网络连接是否正常?
  • 服务器是否运行?

📊 统计信息

服务器日志

登录成功:

用户 Alice 已登录,当前在线: 1

登录失败:

用户名 Alice 已被使用,拒绝登录

用户离线:

用户 Alice 已离线,当前在线: 0

监控建议

  1. 实时监控在线用户数

    tail -f server.log | grep "当前在线"
    
  2. 监控登录失败

    tail -f server.log | grep "拒绝登录"
    
  3. 监控用户活动

    tail -f server.log | grep "用户"
    

🔐 安全考虑

防止恶意占用

虽然当前实现是先到先得,但可以考虑以下增强:

  1. 用户认证

    • 添加密码验证
    • 使用Token认证
  2. 用户名预留

    • 管理员预留特殊用户名
    • 防止敏感词作为用户名
  3. 频率限制

    • 限制同一IP的登录频率
    • 防止暴力尝试
  4. 用户名黑名单

    • 禁止使用敏感词
    • 禁止使用系统保留名称

📝 总结

  • 用户名必须唯一
  • 重复登录会被拒绝
  • 用户离线后用户名自动释放
  • 清晰的错误提示
  • 良好的用户体验

访问 http://120.46.87.202:8080 立即体验!