是什么取代了.Net Core中的WCF?

Sig*_*gex 55 .net c# service wcf .net-core

我习惯于创建一个.Net Framework控制台应用程序,并Add(int x, int y)通过WCF服务从头开始使用类库(.Net Framework)公开一个函数.然后我使用控制台应用程序在服务器内代理调用此函数.

但是,如果我使用Console App(.Net Core)和类库(.Net Core),则System.ServiceModel不可用.我做了一些谷歌搜索,但我还没有弄清楚在这个例子中"替换"WCF.

如何将Add(int x, int y)类库中的函数公开到.Net Core中的控制台应用程序?我看到System.ServiceModel.Web,因为这是尝试跨平台,我是否必须创建RESTful服务?

Gop*_*opi 34

您可以使用gRPC在.NET核心应用程序中托管Web服务.

在此输入图像描述

介绍

  1. gRPC是一个最初由Google开发的高性能开源RPC框架.
  2. 该框架基于远程过程调用的客户端 - 服务器模型.客户端应用程序可以直接调用服务器应用程序上的方法,就像它是本地对象一样.

服务器代码

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

客户代码

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

客户端和服务器之间的共享类

[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; }
}
Run Code Online (Sandbox Code Playgroud)

服务描述符

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));
}
Run Code Online (Sandbox Code Playgroud)

串行器/解串器

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

客户端输出示例

示例服务器输出

参考

  1. https://blogs.msdn.microsoft.com/dotnet/2018/12/04/announcing-net-core-3-preview-1-and-open-sourcing-windows-desktop-frameworks/
  2. https://grpc.io/docs/
  3. https://grpc.io/docs/quickstart/csharp.html
  4. https://github.com/grpc/grpc/tree/master/src/csharp

基准

  1. http://csharptest.net/787/benchmarking-wcf-compared-to-rpclibrary/index.html

  • 截至2019年3月,此答案更为相关。请参阅https://github.com/grpc/grpc-dotnet(和[.NET Core 3.0中的ASP.NET Core更新](https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in -net-core-3-0-preview-3 /))。 (4认同)
  • 另请注意,截至目前,`gRPC` 无法针对 VS 2019 (16.0.2) 中的 .net 本机工具链进行编译,因此无法与 UWP 一起使用。 (4认同)
  • 我认为这是最接近的答案,但遗憾的是,它仍然没有提供任何行为或限制支持。 (2认同)
  • 如果您正在寻找命名管道支持,我编写了一个 gRPC 传输:https://github.com/cyanfish/grpc-dotnet-namedpipes (2认同)

小智 25

.NET Core不支持WCF,因为它是Windows特定技术,而.NET Core应该是跨平台的.如果您正在实施进程间通信,请考虑尝试此项目.它允许以WCF样式创建服务:

第1步 - 创建服务合同

public interface IComputingService
{
    float AddFloat(float x, float y);
}
Run Code Online (Sandbox Code Playgroud)

第2步:实施服务

class ComputingService : IComputingService
{
    public float AddFloat(float x, float y)
    {
        return x + y;
    }
}
Run Code Online (Sandbox Code Playgroud)

第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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

第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));
Run Code Online (Sandbox Code Playgroud)

  • WCF在其抽象的某些协议中可能被视为特定于Windows的窗口,但SOAP服务却并非如此。如何在.net核心中创建SOAP Web服务? (4认同)
  • 太好了!可能值得更新以利用.Net核心系统.io.pipelines https://blogs.msdn.microsoft.com/dotnet/2018/07/09/system-io-pipelines-high-performance-io-in -净/ (3认同)
  • 是的,您缺少的是,这简要说明了 IpcServiceFramework 与 WCF 一样,允许您在不同的消息传递技术之间进行无缝切换。 (3认同)
  • 注:该项目的作者写了以下评论:“伙计们,由于个人原因,我几个月来确实没有时间维护这个项目。同时.NET Core 3.0 发布了 gRPC 功能。” (https://github.com/jacqueskang/IpcServiceFramework/issues/84#issuecomment-556247986)。请参阅 gRPC 的第二个答案。 (3认同)
  • WCF 不是一种“Windows 特定技术”,而是一种实现可互操作的 SOAP/WSDL 堆栈的 .NET 方法。不支持它的 Web 框架无法轻松连接到数千个已实现的服务。这绝对是未来 .NET Core 中必须解决的问题。 (2认同)

Raf*_*ski 15

似乎将有一个.NET Foundation在Microsoft支持下维护的Core WCF项目。此处有更多详细信息:https : //www.dotnetfoundation.org/blog/2019/06/07/welcoming-core-wcf-to-the-net-foundation

最初仅将实现netTcp和http传输。

  • @user1034912 你不正确。CoreWCF是移植到.NET core的轻量级WCF服务器。它有局限性,但对于某些情况来说它是一个不错的选择。 (2认同)

Sly*_*hon 11

WCF 做很多事情;使用命名管道在一台机器上的两个应用程序(进程)之间进行远程过程调用是一种简单的方法;它可以是 .NET 组件之间的高容量内部客户端 - 服务器通信通道,使用 TCPIP 上的二进制序列化;或者它可以提供标准化的跨技术 API,例如通过 SOAP。它甚至通过 MSMQ 支持诸如异步消息传递之类的东西。

对于 .NET Core,根据用途有不同的替代品。

对于跨平台 API,您可以将其替换为使用 ASP.NET 的 REST 服务。

对于进程间连接或客户端-服务器连接,gRPC 会很好,@Gopi 给出了很好的答案。

因此,“什么取代 WCF”的答案取决于您使用它的目的。


ore*_*bac 6

有一个社区存储库https://github.com/CoreWCF/CoreWCF实现了 WCF 的某些部分。您可以使用它来支持一些简单的 WCF 服务。但是,并非所有功能都受支持。


yun*_*nus 5

.NET 5 / Windows Communication Foundation 中的新增功能

Windows Communication Foundation (WCF) 的原始实现仅在 Windows 上受支持。但是,.NET Foundation 提供了一个可用的客户端端口。它是完全开源、跨平台的,并由 Microsoft 支持。

社区维护服务器组件来补充上述客户端库。GitHub 存储库可以在 CoreWCF 中找到。服务器组件不受 Microsoft 官方支持。对于 WCF 的替代方案,请考虑gRPC