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
相关产品推荐
相关产品推荐

