Что заменяет WCF в .Net Core?
Я привык создавать консольное приложение .Net Framework и демонстрировать функцию Add(int x, int y)
через службу WCF с нуля с помощью библиотеки классов (.Net Framework). Затем я использую консольное приложение для прокси-вызова этой функции на сервере.
Однако если я использую консольное приложение (.Net Core) и библиотеку классов (.Net Core), System.ServiceModel будет недоступен. Я немного погуглил, но не понял, что "заменяет" WCF в этом случае.
Как открыть функцию Add(int x, int y)
в библиотеке классов для консольного приложения, все в .Net Core? Я вижу System.ServiceModel.Web, и, поскольку он пытается быть кроссплатформенным, мне нужно создать службу RESTful?
Ответы
Ответ 1
WCF не поддерживается в .NET Core, поскольку это технология, специфичная для Windows, в то время как .NET Core предполагается кроссплатформенной. Если вы внедряете межпроцессное взаимодействие, попробуйте этот проект. Позволяет создавать сервисы в стиле WCF:
Шаг 1 - Создать сервисный контракт
public interface IComputingService
{
float AddFloat(float x, float y);
}
Шаг 2: Внедрить сервис
class ComputingService : IComputingService
{
public float AddFloat(float x, float y)
{
return x + y;
}
}
Шаг 3 - Хост сервис в Консольном приложении
class Program
{
static void Main(string[] args)
{
// configure DI
IServiceCollection services = ConfigureServices(new ServiceCollection());
// build and run service host
new IpcServiceHostBuilder(services.BuildServiceProvider())
.AddNamedPipeEndpoint<IComputingService>(name: "endpoint1", pipeName: "pipeName")
.AddTcpEndpoint<IComputingService>(name: "endpoint2", ipEndpoint: IPAddress.Loopback, port: 45684)
.Build()
.Run();
}
private static IServiceCollection ConfigureServices(IServiceCollection services)
{
return services
.AddIpc()
.AddNamedPipe(options =>
{
options.ThreadCount = 2;
})
.AddService<IComputingService, ComputingService>();
}
}
Шаг 4 - Вызов службы из процесса клиента
IpcServiceClient<IComputingService> client = new IpcServiceClientBuilder<IComputingService>()
.UseNamedPipe("pipeName") // or .UseTcp(IPAddress.Loopback, 45684) to invoke using TCP
.Build();
float result = await client.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
Ответ 2
Вы можете использовать gRPC для размещения веб-сервисов внутри основного приложения .NET.
![enter image description here]()
Вступление
- gRPC - это высокопроизводительная среда RPC с открытым исходным кодом, изначально разработанная Google.
- Структура основана на клиент-серверной модели удаленных вызовов процедур. Клиентское приложение может напрямую вызывать методы серверного приложения, как если бы оно было локальным объектом.
пример
Код сервера
class Program
{
static void Main(string[] args)
{
RunAsync().Wait();
}
private static async Task RunAsync()
{
var server = new Grpc.Core.Server
{
Ports = { { "127.0.0.1", 5000, ServerCredentials.Insecure } },
Services =
{
ServerServiceDefinition.CreateBuilder()
.AddMethod(Descriptors.Method, async (requestStream, responseStream, context) =>
{
await requestStream.ForEachAsync(async additionRequest =>
{
Console.WriteLine($"Recieved addition request, number1 = {additionRequest.X} --- number2 = {additionRequest.Y}");
await responseStream.WriteAsync(new AdditionResponse {Output = additionRequest.X + additionRequest.Y});
});
})
.Build()
}
};
server.Start();
Console.WriteLine($"Server started under [127.0.0.1:5000]. Press Enter to stop it...");
Console.ReadLine();
await server.ShutdownAsync();
}
}
Код клиента
class Program
{
static void Main(string[] args)
{
RunAsync().Wait();
}
private static async Task RunAsync()
{
var channel = new Channel("127.0.0.1", 5000, ChannelCredentials.Insecure);
var invoker = new DefaultCallInvoker(channel);
using (var call = invoker.AsyncDuplexStreamingCall(Descriptors.Method, null, new CallOptions{}))
{
var responseCompleted = call.ResponseStream
.ForEachAsync(async response =>
{
Console.WriteLine($"Output: {response.Output}");
});
await call.RequestStream.WriteAsync(new AdditionRequest { X = 1, Y = 2});
Console.ReadLine();
await call.RequestStream.CompleteAsync();
await responseCompleted;
}
Console.WriteLine("Press enter to stop...");
Console.ReadLine();
await channel.ShutdownAsync();
}
}
Общие классы между клиентом и сервером
[Schema]
public class AdditionRequest
{
[Id(0)]
public int X { get; set; }
[Id(1)]
public int Y { get; set; }
}
[Schema]
public class AdditionResponse
{
[Id(0)]
public int Output { get; set; }
}
Сервисные дескрипторы
using Grpc.Core;
public class Descriptors
{
public static Method<AdditionRequest, AdditionResponse> Method =
new Method<AdditionRequest, AdditionResponse>(
type: MethodType.DuplexStreaming,
serviceName: "AdditonService",
name: "AdditionMethod",
requestMarshaller: Marshallers.Create(
serializer: Serializer<AdditionRequest>.ToBytes,
deserializer: Serializer<AdditionRequest>.FromBytes),
responseMarshaller: Marshallers.Create(
serializer: Serializer<AdditionResponse>.ToBytes,
deserializer: Serializer<AdditionResponse>.FromBytes));
}
Параллельно-последовательный/последовательно-параллельный преобразователь
public static class Serializer<T>
{
public static byte[] ToBytes(T obj)
{
var buffer = new OutputBuffer();
var writer = new FastBinaryWriter<OutputBuffer>(buffer);
Serialize.To(writer, obj);
var output = new byte[buffer.Data.Count];
Array.Copy(buffer.Data.Array, 0, output, 0, (int)buffer.Position);
return output;
}
public static T FromBytes(byte[] bytes)
{
var buffer = new InputBuffer(bytes);
var data = Deserialize<T>.From(new FastBinaryReader<InputBuffer>(buffer));
return data;
}
}
Выход
Пример клиентского вывода
Пример сервера вывода
Рекомендации
- https://blogs.msdn.microsoft.com/dotnet/2018/12/04/announcing-net-core-3-preview-1-and-open-sourcing-windows-desktop-frameworks/
- https://grpc.io/docs/
- https://grpc.io/docs/quickstart/csharp.html
- https://github.com/grpc/grpc/tree/master/src/csharp
Ориентиры
- http://csharptest.net/787/benchmarking-wcf-compared-to-rpclibrary/index.html
Ответ 3
Похоже, что будет основной проект WCF, поддерживаемый .NET Foundation при поддержке Microsoft. Подробнее здесь: https://www.dotnetfoundation.org/blog/2019/06/07/welcoming-core-wcf-to-the-net-foundation
Изначально будут реализованы только транспорт NetTcp и http.
Ответ 4
Итак, из моих исследований лучшее решение не имеет автогенерированных прокси-классов. Это лучшее решение для создания службы RESTful и сериализации тела ответа в объектах модели. Где модели являются обычными объектами модели, найденными в шаблоне проектирования MVC.
Спасибо за ваши отзывы
Ответ 5
Доступен порт .NET Core: https://github.com/dotnet/wcf. Он все еще находится в предварительном просмотре, но его активно развивают.