PHP C#命名管道

时间:2017-10-14 14:12:11

标签: c# php ipc named-pipes

我最近在C#和PHP之间询问了一个关于IPC的问题,然后回答了建议命名管道的问题。为此,我在互联网上搜索了一个适当的命名管道示例,它同时使用C#作为clientserver并进行了修改,以便它以异步方式运行:

static void Main(string[] args)
{
    Start();
    new AutoResetEvent(false).WaitOne();
}

private static async void Start()
{
    StartServer();
    Thread.Sleep(1500);
    StartClient();
}

private static async void StartClient()
{
    var client = new NamedPipeClientStream("TestPipe");
    await client.ConnectAsync();

    var reader = new StreamReader(client);
    var writer = new StreamWriter(client);
    while (true)
    {
        var input = Console.ReadLine();
        if (string.IsNullOrEmpty(input)) break;
        await writer.WriteLineAsync(input);
        await writer.FlushAsync();
        Console.WriteLine(await reader.ReadLineAsync());
    }
}

private static async void StartServer()
{
    await Task.Run(async() =>
    {
        var server = new NamedPipeServerStream("TestPipe");
        await server.WaitForConnectionAsync(); 
        var reader = new StreamReader(server);
        var writer = new StreamWriter(server);
        while(true) // should be !reader.EndOfStream(), doesn't work tho
        {
            var line = await reader.ReadLineAsync();
            await writer.WriteLineAsync("RECEIVED > " + line);
            await writer.FlushAsync();
        }
    });
}

因此,如果我现在在控制台中键入Hello,它将返回RECEIVED > Hello,这很好,看起来它非常出色。我在C#中完全理解这一点。然而,当PHP发挥作用时,这会发生变化:我发现在PHP中使用命名管道的不太好的示例(甚至是教程)。现在我发现here让我更进了一步,但只有一步。

在PHP中,我似乎缺乏对整个复杂的理解。我的目标是以命令的形式(例如create document id=12)向我的C#服务器“提供”任务。服务器(也在很大程度上是异步运行的)然后应该回馈一下它是否已经解决(也使用id)。例如,我的服务器的回复可能是:

document id=12 created successfully

document id=12 error

当然,我需要我的两个应用程序来解析它并进一步处理这些回复,但是,这不是此时的问题。我需要我的PHP应用程序将任务安排到C#并获得'ping-back'('错误与否',你可以说)。我甚至不需要多次ping回来,所以例如C#应用程序的状态更新经常发送它,我只需要一个最终语句是否有效。

看看我在php.net上找到的例子,这并没有告诉我太多关于它的事情:

<?php
   $pipe="/tmp/pipe";
   $mode=0600;
   if(!file_exists($pipe)) {
      // create the pipe
      umask(0);
      posix_mkfifo($pipe,$mode);
   }
   $f = fopen($pipe,"w");
   fwrite($f,"hello");  //block until there is a reader
   unlink($pipe); //delete pipe

?>

这是非阻塞读者:

<?php
   $pipe="/tmp/pipe";
   if(!file_exists($pipe)) {
      echo "I am not blocked!";
   }
   else {
      //block and read from the pipe
      $f = fopen($pipe,"r");
      echo fread($f,10);
   }
?>

第一个阻止变体不符合Windows的条件,因为Windows上没有posix,而我的C#应用​​程序需要这个。这个例子显示了一个被阻塞的管道(这究竟是什么?我可以想到一个被认为是被阻塞的现有管道,因为if(!file_exists($pipe))建议这样做)。但是,这意味着我只能使用我的C#服务器同时处理一项任务,这不是必需的。

这是应该采用的程序:

  1. 用户按下'下载'
  2. 启动PHP操作(在我的Laravel Controller内)
  3. PHP通过管道
  4. 将任务安排到C#服务器
  5. C#服务器接收并处理它
  6. C#服务器完成它并通过管道告诉PHP它已完成(或分别抛出错误)
  7. PHP(Laravel Controller)已经等待这个答案并将其呈现给用户
  8. 我遇到的问题是可以阻止管道的地方,因为这(根据PHP文档页面评论部分的参考)将意味着如果某个管道被阻止并且我希望在该管道上运行多个任务同时,我需要创建一个新的,我的C#服务器也必须知道,这总结意味着我只能设置非常有限数量的管道,所以说'可能'的插槽用于'工作'或'服务器的任务',Web应用程序的用户可以加入[插槽],然后清除插槽。无论如何,这会破坏我的C#异步服务器的概念及其背后的主要思想,我不能认为这是唯一的解决方案。

    我期待看到一些建议。干杯!

0 个答案:

没有答案