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

Socket编程问题:客户端无法实时接收服务器推送消息

游戏Socket编程消息阻塞问题分析与修复

问题背景

服务器每0.2秒(一个游戏tick)会通过sendGameWorldSections()方法向已连接客户端发送游戏世界数据,该操作单独开线程执行以避免阻塞游戏主循环。但客户端无法实时接收消息,仅在关闭客户端时才会批量显示所有积压的消息,需排查问题根源。

核心问题定位

1. 服务器发送端:缺少换行符+未触发流刷新

服务器sendMessageToPlayer方法存在关键问题:

public static void sendMessageToPlayer(String playerID, String message) throws IOException {
    System.out.println("Sending message..");
    Socket socket = playerIDToSocket.get(playerID);
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.print(message);
}
  • 客户端使用in.readLine()接收消息,该方法会阻塞直到读取到换行符\n或流关闭,但服务器仅发送JSON字符串,未添加换行符;
  • 虽然PrintWriter构造时开启了autoFlush,但该特性仅在调用println()/printf()/format()时生效,print()不会触发自动刷新,导致消息一直积压在输出缓冲区,直到缓冲区满或连接关闭才会发送。

2. 客户端接收端:单次读取逻辑缺陷

客户端listen方法仅调用一次in.readLine(),若服务器未发送换行符,该方法会一直阻塞,直到流关闭时才会一次性读取所有缓冲数据,这就是关闭客户端才批量显示消息的直接原因。

修复方案

服务器端修改(核心修复)

修改sendMessageToPlayer方法,使用println()自动添加换行符并触发刷新:

public static void sendMessageToPlayer(String playerID, String message) throws IOException {
    System.out.println("Sending message..");
    Socket socket = playerIDToSocket.get(playerID);
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    out.println(message); // 自动添加换行符,同时触发autoFlush
}

若坚持使用print(),需手动添加换行并强制刷新:

out.print(message + "\n");
out.flush();

客户端优化(可选)

调整监听逻辑为持续读取模式,确保能实时处理每条消息:

public void listen(BufferedReader in){
    String message;
    try {
        // 持续读取直到流关闭
        while ((message = in.readLine()) != null) {
            System.out.println("[SERVER]: " + message);
            if(isJSONValid(message)){
                // 原有JSON解析与游戏逻辑处理
            }
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}

额外优化建议

  • 静态playerIDToSocket未做并发同步,多线程访问可能出现异常,建议替换为ConcurrentHashMap或添加同步锁;
  • GameTicker每次tick创建新线程的方式存在性能开销,建议使用线程池管理发送任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 08:21:57