通过命名管道访问 Windows 上的 Docker API
Access Docker API on Windows via Named Pipes
根据 Docker for Windows FAQ,“客户端可以通过命名管道连接到 Docker 引擎:npipe:////。/pipe/docker_engine"
我一直在尝试通过命名管道连接到 API 但无济于事:
public class DockerNamedPipeTest
{
private const string PIPE_PATH = "docker_engine";
public void Test()
{
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(
".",
PIPE_PATH,
PipeDirection.InOut,
PipeOptions.WriteThrough,
TokenImpersonationLevel.Impersonation))
{
pipeClient.Connect(30);
Send(pipeClient);
Receive(pipeClient);
}
}
public void Send(NamedPipeClientStream pipeClient)
{
if (pipeClient.IsConnected)
{
byte[] buffer = Encoding.UTF8.GetBytes("GET /containers/json");
pipeClient.Write(buffer, 0, buffer.Length);
pipeClient.WaitForPipeDrain();
pipeClient.Flush();
}
}
public void Receive(NamedPipeClientStream pipeClient)
{
string result = string.Empty;
if (pipeClient.IsConnected && pipeClient.CanRead)
{
do
{
byte b = (byte)pipeClient.ReadByte(); // <-- Hangs here
result += Convert.ToChar(b).ToString();
}
while (!pipeClient.IsMessageComplete);
}
Console.WriteLine(result);
}
}
谁能告诉我我做错了什么?
Microsoft .NET client library for Docker 支持命名管道,你看过了吗?
这是一个例子:
using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine"))
.CreateClient();
事实证明,答案可以在Docker.DotNet代码的源代码中找到,具体在DockerPipeStream.cs class中调用CloseWrite()
的方法中:
(https://github.com/Microsoft/Docker.DotNet/blob/master/src/Docker.DotNet/DockerPipeStream.cs)
// The Docker daemon expects a write of zero bytes to signal the end of writes. Use native
// calls to achieve this since CoreCLR ignores a zero-byte write.
我将此方法应用到我的代码中,代码不再挂起。
我现在收到 400 Bad Request 但至少现在我知道为什么与 docker 守护进程的通信挂起了。如果 Docker for Windows FAQ 提到了这个细微差别,那就太好了。
根据 Docker for Windows FAQ,“客户端可以通过命名管道连接到 Docker 引擎:npipe:////。/pipe/docker_engine"
我一直在尝试通过命名管道连接到 API 但无济于事:
public class DockerNamedPipeTest
{
private const string PIPE_PATH = "docker_engine";
public void Test()
{
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(
".",
PIPE_PATH,
PipeDirection.InOut,
PipeOptions.WriteThrough,
TokenImpersonationLevel.Impersonation))
{
pipeClient.Connect(30);
Send(pipeClient);
Receive(pipeClient);
}
}
public void Send(NamedPipeClientStream pipeClient)
{
if (pipeClient.IsConnected)
{
byte[] buffer = Encoding.UTF8.GetBytes("GET /containers/json");
pipeClient.Write(buffer, 0, buffer.Length);
pipeClient.WaitForPipeDrain();
pipeClient.Flush();
}
}
public void Receive(NamedPipeClientStream pipeClient)
{
string result = string.Empty;
if (pipeClient.IsConnected && pipeClient.CanRead)
{
do
{
byte b = (byte)pipeClient.ReadByte(); // <-- Hangs here
result += Convert.ToChar(b).ToString();
}
while (!pipeClient.IsMessageComplete);
}
Console.WriteLine(result);
}
}
谁能告诉我我做错了什么?
Microsoft .NET client library for Docker 支持命名管道,你看过了吗?
这是一个例子:
using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine"))
.CreateClient();
事实证明,答案可以在Docker.DotNet代码的源代码中找到,具体在DockerPipeStream.cs class中调用CloseWrite()
的方法中:
(https://github.com/Microsoft/Docker.DotNet/blob/master/src/Docker.DotNet/DockerPipeStream.cs)
// The Docker daemon expects a write of zero bytes to signal the end of writes. Use native
// calls to achieve this since CoreCLR ignores a zero-byte write.
我将此方法应用到我的代码中,代码不再挂起。
我现在收到 400 Bad Request 但至少现在我知道为什么与 docker 守护进程的通信挂起了。如果 Docker for Windows FAQ 提到了这个细微差别,那就太好了。