我一直关注this post on Medium,以学习如何在Docker容器中创建和运行dotnet核心控制台应用程序,以及如何在另一个容器中发布到dotnet核心API。
当我并排运行两个应用程序(没有docker,即仅在vscode中调试)时,一切正常,控制台应用程序可以发布到API。但是,当我使用docker-compose up --build
在容器中运行应用程序时,当应用程序尝试发布到api时会出现错误:
未处理的异常。 System.AggregateException:发生一个或多个错误。 (无法建立SSL连接,请参阅内部异常。)
System.Net.Http.HttpRequestException:无法建立SSL连接,请参阅内部异常。
System.IO.IOException:由于意外的数据包格式,握手失败。
寻找该错误的解决方案并没有多大帮助,我觉得问题可能仅仅是两个容器之间的连通性,但是我没有运气去解决它。
我的docker-compose
文件如下:
version: '3.4'
services:
publisher_api:
image: my_publisher_api:latest
container_name: my_publisher_api_container
build:
context: ./publisher_api
dockerfile: Dockerfile
worker:
image: my_worker
container_name: my_worker_container
depends_on:
- "publisher_api"
build:
context: ./worker
dockerfile: Dockerfile
我的控制台应用程序代码(或至少相关部分)是:
public static async Task PostMessage(object postData)
{
var json = JsonConvert.SerializeObject(postData);
var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
var result = await client.PostAsync("https://my_publisher_api_container:80/values", content);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine($"Server returned {resultContent}");
}
}
}
我不会发布任何API代码,因为我认为其中任何一个都不相关,但是如果您认为有帮助,请告诉我。
如果有人对导致此错误的原因或解决方法有任何了解,我将非常感谢您的帮助。
认为包括正在使用的版本会很有用:
3.0.101
19.03.5, build 633a0ea838
答案 0 :(得分:0)
看起来我犯了两个相当明显的错误,但是当您像我一样完全不熟悉Docker时,这些错误并不那么明显。
要发布的主机名应该是服务的名称,不是容器的 。在我的情况下,我不得不更改控制台应用程序以将其发布为API服务的名称在docker-compose文件publisher_api
中声明。
使用HTTP代替HTTPS。当我在本地调试API时,默认情况下会使用HTTPS启动。我以为在docker中运行容器时会使用HTTPS,但是默认情况下这似乎不起作用。更改为HTTP可以解决此问题(尽管理想情况下这是一个短期解决方案)。
因此,为了完整起见,这是我更新的代码。只需更改控制台应用程序发布到的URL:
public static async Task PostMessage(object postData)
{
var json = JsonConvert.SerializeObject(postData);
var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
var result = await client.PostAsync("http://publisher_api80/values", content);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine($"Server returned {resultContent}");
}
}
}