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

Stride引擎SendReceiveAsync异步方法调用及报错问题咨询

问题解决方案

1. 现有报错修复

  • 删除多余的自定义SendReceiveAsync方法:你类中自行编写的同名方法完全冗余,SocketMessageLayer已经内置了实现完成的SendReceiveAsync逻辑,无需自行重写,这是你第一个返回值类型不匹配报错的直接原因。
  • 补充空对象初始化:你的SimpleSocket类型字段SS没有实例化就直接调用方法,运行会直接抛出空引用异常,在Start方法中添加SS = new SimpleSocket();即可。
  • 补充SocketMessage参数构造逻辑:SendReceiveAsync的参数query是你要发送的请求消息,需要自行构造实例,示例如下:
// 构造请求消息
var sendMsg = new SocketMessage();
// 往消息流中写入数据,示例写入字符串
using (var writer = new BinaryWriter(sendMsg.Data))
{
    writer.Write("要发送的消息内容");
}
// 发送消息并等待响应
SocketMessage result = await SML.SendReceiveAsync(sendMsg);
// 读取响应内容
using (var reader = new BinaryReader(result.Data))
{
    var responseContent = reader.ReadString();
}
  • 注释取消后语法报错修复:该报错和async逻辑无关,是你省略的代码存在语法问题,比如分号遗漏、括号不匹配,逐行检查代码语法即可。

2. 完整可用的收发代码示例

using System;
using System.IO;
using System.Threading.Tasks;
using Stride.Engine;
using Stride.Engine.Network;
using Stride.Input;

namespace MyGame
{
    public class Net : SyncScript
    {
        public SimpleSocket SS;
        public SocketMessageLayer SML;
        private bool _isServer;

        // 启动服务端
        public void StartServer()
        {
            _isServer = true;
            SS = new SimpleSocket();
            SML = new SocketMessageLayer(SS, true);
            SS.StartServer(21, true, 1);
            // 后台启动服务端消息监听循环
            _ = RunServerReceiveLoop();
        }

        // 启动客户端
        public void StartClient()
        {
            _isServer = false;
            SS = new SimpleSocket();
            SML = new SocketMessageLayer(SS, false);
            SS.StartClient("127.0.0.1", 21, true);
        }

        // 客户端发送消息并获取响应的示例方法
        public async Task<string> SendMessageToServer(string sendContent)
        {
            var sendMsg = new SocketMessage();
            using (var writer = new BinaryWriter(sendMsg.Data))
            {
                writer.Write(sendContent);
            }
            var responseMsg = await SML.SendReceiveAsync(sendMsg);
            using (var reader = new BinaryReader(responseMsg.Data))
            {
                return reader.ReadString();
            }
        }

        // 服务端接收消息+返回响应的循环逻辑
        private async Task RunServerReceiveLoop()
        {
            while (true)
            {
                // 监听客户端发来的消息
                var receiveMsg = await SML.ReceiveAsync();
                // 读取请求内容
                string requestContent;
                using (var reader = new BinaryReader(receiveMsg.Data))
                {
                    requestContent = reader.ReadString();
                }
                // 构造响应消息
                var responseMsg = new SocketMessage();
                using (var writer = new BinaryWriter(responseMsg.Data))
                {
                    writer.Write($"服务端已收到消息:{requestContent}");
                }
                // 返回响应给客户端
                await SML.SendAsync(responseMsg);
            }
        }

        public override void Start()
        {
            // 测试时可启动两个实例,分别执行服务端/客户端启动逻辑
            // StartServer();
            // StartClient();
        }

        public override void Update()
        {
            // 测试:客户端按S键发送消息
            if (Input.IsKeyPressed(Keys.S) && !_isServer)
            {
                _ = SendMessageToServer("客户端测试消息");
            }
        }
    }
}

3. 运行逻辑说明

  • SendReceiveAsync是封装好的请求-响应模式方法,仅需在客户端调用,发送请求后会自动等待服务端返回对应响应,无需自行处理收发配对逻辑
  • 服务端无需调用SendReceiveAsync,配合使用ReceiveAsync收消息、SendAsync发响应即可实现消息处理
  • 所有async方法不要使用同步等待(比如.Wait()、.Result),会卡住游戏主线程,用_ = 方法名()的形式丢后台运行即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:09:03