-
Notifications
You must be signed in to change notification settings - Fork 30
Open
Description
在 Linux 下的 UOS 系统里面进行测试,如以下代码
var peer = await ipcProvider.GetAndConnectToPeerAsync(args[0]);
peer.MessageReceived += (sender, messageArgs) =>
{
Console.WriteLine(
$"[{Environment.ProcessId}] 收到 {peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");
};
await peer.NotifyAsync(new IpcMessage("Hello",
Encoding.UTF8.GetBytes($"Hello,进程号是 {Environment.ProcessId} 发送过来消息")));
Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");
Console.Read();那么以上的 MessageReceived 事件将不会被触发,且是因为底层的管道读取无法返回。一旦使用 Task.Run 包括起来,如以下代码,即可正常收到消息
Task.Run(async () =>
{
var peer = await ipcProvider.GetAndConnectToPeerAsync(args[0]);
peer.MessageReceived += (sender, messageArgs) =>
{
Console.WriteLine(
$"[{Environment.ProcessId}] 收到 {peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");
};
await peer.NotifyAsync(new IpcMessage("Hello",
Encoding.UTF8.GetBytes($"Hello,进程号是 {Environment.ProcessId} 发送过来消息")));
Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");
});
Console.Read();如果给 Task.Run 加上 await 如以下代码,那将无法收到回复,依然是管道读取没有返回,可参考 91043ee 的更改
await Task.Run(async () =>
{
var peer = await ipcProvider.GetAndConnectToPeerAsync(args[0]);
peer.MessageReceived += (sender, messageArgs) =>
{
Console.WriteLine(
$"[{Environment.ProcessId}] 收到 {peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");
};
await peer.NotifyAsync(new IpcMessage("Hello",
Encoding.UTF8.GetBytes($"Hello,进程号是 {Environment.ProcessId} 发送过来消息")));
Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");
});
Console.Read();以上代码情况可以排除 Task Main 导致的问题,因为一旦将 Console.Read 换掉,那就可以正常读取到管道里面的消息,管道可以返回,如 8d27486 代码更改
await Task.Run(async () =>
{
var peer = await ipcProvider.GetAndConnectToPeerAsync(args[0]);
peer.MessageReceived += (sender, messageArgs) =>
{
Console.WriteLine(
$"[{Environment.ProcessId}] 收到 {peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");
};
await peer.NotifyAsync(new IpcMessage("Hello",
Encoding.UTF8.GetBytes($"Hello,进程号是 {Environment.ProcessId} 发送过来消息")));
Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");
});
for (int i = 0; i < int.MaxValue; i++)
{
await Task.Delay(TimeSpan.FromSeconds(1));
}以上问题的简单复现代码:
internal class Program
{
private static async Task Main(string[] args)
{
var ipcProvider = new IpcProvider();
ipcProvider.StartServer();
if (args.Length == 0)
{
var currentName = ipcProvider.IpcContext.PipeName;
// 将当前的进程的 Name 传递给另一个进程,用来达成通讯
var mainModuleFileName = Process.GetCurrentProcess().MainModule.FileName;
Console.WriteLine($"[{Environment.ProcessId}] 准备启动 {mainModuleFileName} 参数:{currentName}");
Process.Start(mainModuleFileName, currentName);
}
else
{
// 这是被启动的进程,主动连接发送消息
Console.WriteLine($"[{Environment.ProcessId}] 开始连接对方进程");
var peer = await ipcProvider.GetAndConnectToPeerAsync(args[0]);
peer.MessageReceived += (sender, messageArgs) =>
{
Console.WriteLine(
$"[{Environment.ProcessId}] 收到 {peer.PeerName} 的回复消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");
};
await peer.NotifyAsync(new IpcMessage("Hello",
Encoding.UTF8.GetBytes($"Hello,进程号是 {Environment.ProcessId} 发送过来消息")));
Console.WriteLine($"[{Environment.ProcessId}] 完成发送消息");
}
ipcProvider.PeerConnected += (sender, connectedArgs) =>
{
Console.WriteLine($"[{Environment.ProcessId}] 收到 {connectedArgs.Peer.PeerName} 的连接");
connectedArgs.Peer.MessageReceived += async (o, messageArgs) =>
{
Console.WriteLine($"[{Environment.ProcessId}] 收到 {messageArgs.PeerName} 的消息:{Encoding.UTF8.GetString(messageArgs.Message.Body.AsSpan())}");
await Task.Delay(TimeSpan.FromSeconds(1));
// 反向发送消息给对方
Console.WriteLine($"[{Environment.ProcessId}] 向 {connectedArgs.Peer.PeerName} 回复消息");
await connectedArgs.Peer.NotifyAsync(new IpcMessage("回复", Encoding.UTF8.GetBytes($"收到你的消息")));
Console.WriteLine($"[{Environment.ProcessId}] 完成向 {connectedArgs.Peer.PeerName} 回复消息");
};
};
Console.WriteLine($"[{Environment.ProcessId}] 等待退出");
Console.Read();
Console.WriteLine($"[{Environment.ProcessId}] 进程准备退出");
}
}以上代码在 Windows 上正常,在 Linux 的 UOS 系统无法收到回复消息,也就是 peer.MessageReceived 对应的事件没有触发,调试可以看到管道没有读取返回
详细的各个测试步骤请看 #140
可能是 Linux 的 Console.Read 投毒
Metadata
Metadata
Assignees
Labels
No labels