Điều gì thay thế WCF trong .Net Core?


97

Tôi đã quen với việc tạo ứng dụng bảng điều khiển .Net Framework và hiển thị một Add(int x, int y)chức năng thông qua dịch vụ WCF từ đầu với Thư viện lớp (.Net Framework). Sau đó, tôi sử dụng ứng dụng bảng điều khiển để proxy gọi hàm này trong máy chủ.

Tuy nhiên, nếu tôi sử dụng Ứng dụng Console (.Net Core) và Thư viện lớp (.Net Core) thì System.ServiceModel không khả dụng. Tôi đã thực hiện một số Googling nhưng tôi chưa tìm ra cái gì "thay thế" WCF trong trường hợp này.

Làm cách nào để hiển thị một Add(int x, int y)hàm trong thư viện lớp cho một ứng dụng bảng điều khiển trong .Net Core? Tôi thấy System.ServiceModel.Web, và vì nó đang cố gắng trở thành nền tảng chéo nên tôi có phải tạo một dịch vụ RESTful không?


do I have to create a RESTful service?- AFAIK có (hoặc sử dụng một số giải pháp của hãng thứ 3 tôi sẽ không biết bất kỳ cho NET Core)
Christoph Fink

3
WCF có thể sẽ không được chuyển sang .NET Core, vì hầu hết cơ sở mã phụ thuộc vào các thư viện nội bộ của Windows. Bạn có thể sử dụng ASP.NET Core không? Ở đó, bạn sẽ có một máy chủ HTTP dễ dàng đa nền tảng
Camilo Terevinto,

2
WCF phía máy khách đã được hỗ trợ (tôi không biết bao nhiêu), phía máy chủ là một yêu cầu tính năng được tranh luận sôi nổi và được tán thành.
Henk Holterman,

Nó xuất hiện Visual Studio 2017 15.5 trở lên hỗ trợ tạo các lớp proxy máy khách .NET Core . Ngoài ra còn có một danh sách các tính năng được hỗ trợ .
jamiebarrow

5
Tóm lại: CoreWCF
Ognyan Dimitrov

Câu trả lời:


35

WCF không được hỗ trợ trong .NET Core vì đây là một công nghệ dành riêng cho Windows và .NET Core được cho là đa nền tảng.

Nếu bạn đang triển khai giao tiếp giữa các quá trình, hãy xem xét thử dự án IpcServiceFramework .

Nó cho phép tạo các dịch vụ theo kiểu WCF như sau:

  1. Tạo hợp đồng dịch vụ

    public interface IComputingService
    {
        float AddFloat(float x, float y);
    }
    
  2. Triển khai dịch vụ

    class ComputingService : IComputingService
    {
        public float AddFloat(float x, float y)
        {
            return x + y;
        }
    }
    
  3. Lưu trữ dịch vụ trong ứng dụng Bảng điều khiển

    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. Gọi dịch vụ từ quy trình khách hàng

    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));
    

3
Đẹp! Có thể là giá trị cập nhật để tận dụng lợi thế của system.io.pipelines lõi Net blogs.msdn.microsoft.com/dotnet/2018/07/09/...
Sigex

Xin lỗi, tôi có thiếu thứ gì đó quan trọng ở đây không? Không phải các đường ống được cho là chỉ dành cho truyền thông cùng một máy chủ?
user1034912

2
Vâng, điều bạn còn thiếu là điều này minh chứng ngắn gọn rằng IpcServiceFramework, giống như WCF, cho phép bạn chuyển đổi liền mạch giữa các công nghệ nhắn tin khác nhau.
Chris F Carroll

4
WCF có thể được coi là cửa sổ cụ thể trong một số giao thức mà nó tóm tắt, nhưng các dịch vụ SOAP thì không. Làm thế nào để tạo một dịch vụ web SOAP trong lõi .net?
Jeremy

3
Lưu ý: tác giả của dự án này đã viết nhận xét như sau: "Các bạn, vì lý do cá nhân, tôi không có thời gian để duy trì dự án này kể từ vài tháng. Trong khi đó .NET Core 3.0 được phát hành với tính năng gRPC." ( github.com/jacqueskang/IpcServiceFramework/issues/… ). Xem câu trả lời thứ hai cho gRPC.
gerard

64

Bạn có thể sử dụng gRPC để lưu trữ các dịch vụ web bên trong ứng dụng lõi .NET.

nhập mô tả hình ảnh ở đây

Giới thiệu

  1. gRPC là một khung RPC mã nguồn mở, hiệu suất cao được phát triển ban đầu bởi Google.
  2. Khung công tác dựa trên mô hình máy khách-máy chủ của các cuộc gọi thủ tục từ xa. Ứng dụng khách có thể gọi trực tiếp các phương thức trên ứng dụng máy chủ như thể nó là một đối tượng cục bộ.

Thí dụ

Mã máy chủ

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();
    }
}

Mã khách hàng

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();
    }
}

Các lớp được chia sẻ giữa Máy khách và Máy chủ

[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; }
}

Bộ mô tả dịch vụ

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));
}

Serializer / Deserializer

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;
    }
}

Đầu ra

Đầu ra khách hàng mẫu

Đầu ra máy chủ mẫu

Người giới thiệu

  1. https://blogs.msdn.microsoft.com/dotnet/2018/12/04/annontic-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

Điểm chuẩn

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

7
Kể từ tháng 3 năm 2019, câu trả lời này phù hợp hơn. Xem github.com/grpc/grpc-dotnet (và các bản cập nhật ASP.NET Core trong .NET Core 3.0 ).
resnyanskiy

1
Tôi nghĩ đây là câu trả lời gần nhất nhưng thật đáng buồn, nó không cung cấp bất kỳ hành vi hoặc hỗ trợ điều tiết nào.
joe

4
Cũng xin lưu ý rằng hiện tại gRPCkhông biên dịch theo chuỗi công cụ gốc .net trong VS 2019 (16.0.2) và do đó sẽ không hoạt động với UWP.
Samuel

2
Nếu bạn đang tìm kiếm hỗ trợ đường ống được đặt tên, tôi đã viết một phương tiện truyền tải gRPC: github.com/cyanfish/grpc-dotnet-namepipes
Cyanfish vào

1
Lưu ý rằng (kể từ 2020-04-06) grpc-dotnet không có gói dành cho ARM.
GafferMan2112

23

Có vẻ như sẽ có một dự án CoreWCF do .NET Foundation duy trì với sự hỗ trợ của Microsoft.

Thông tin chi tiết tại Chào mừng WCF Core cho .NET Foundation

Ban đầu chỉ vận chuyển netTcp và http sẽ được thực hiện.


Đây là một câu trả lời sai lầm. Microsoft mới chỉ chuyển ứng dụng wcf. Máy chủ wcf hoặc máy chủ dịch vụ không khả dụng và họ không có ý định làm như vậy. Tôi học được điều này một cách khó khăn. gRPC là con đường để đi
user1034912

@ user1034912 bạn không đúng. CoreWCF là máy chủ WCF nhẹ được chuyển sang lõi .NET. Nó có những hạn chế, nhưng đối với một số trường hợp, nó là một lựa chọn tốt.
Truy cập Bị Từ chối

Có, chỉ khi bạn là Khách hàng tiêu dùng, sẽ không có triển khai dịch vụ lưu trữ
user1034912

@ user1034912 Không, phía máy chủ khả dụng. github.com/CoreWCF/CoreWCF/blob/master/src/Samples/…
Truy cập Bị Từ chối


9

WCF làm được nhiều thứ; đó là một cách dễ dàng để gọi thủ tục từ xa giữa hai ứng dụng (quy trình) trên một máy, sử dụng các đường ống được đặt tên; nó có thể là một kênh giao tiếp máy khách-máy chủ nội bộ khối lượng lớn giữa các thành phần .NET, sử dụng tuần tự hóa nhị phân qua TCPIP; hoặc nó có thể cung cấp một API công nghệ chéo được tiêu chuẩn hóa, ví dụ như qua SOAP. Nó thậm chí còn hỗ trợ những thứ như nhắn tin không đồng bộ, thông qua MSMQ.

Đối với .NET Core, có các thay thế khác nhau dựa trên mục đích.

Đối với API đa nền tảng, bạn sẽ thay thế điều này bằng dịch vụ REST sử dụng ASP.NET.

Đối với kết nối giữa các quá trình hoặc kết nối máy khách-máy chủ, gRPC sẽ tốt, với câu trả lời tuyệt vời được đưa ra bởi @Gopi.

Vì vậy, câu trả lời cho "Cái gì thay thế WCF" phụ thuộc vào việc bạn đang sử dụng nó để làm gì.


5

Có một đại diện cộng đồng https://github.com/CoreWCF/CoreWCF triển khai một số phần của WCF. Bạn có thể sử dụng nó để hỗ trợ một số dịch vụ WCF đơn giản. Tuy nhiên không phải tất cả các tính năng đều được hỗ trợ.


4

Vì vậy, từ nghiên cứu của tôi, giải pháp tốt nhất không có các lớp proxy được tạo tự động. Giải pháp tốt nhất này là tạo một dịch vụ RESTful và tuần tự hóa phần thân phản hồi thành các đối tượng mô hình. Nơi các mô hình là các đối tượng mô hình thông thường được tìm thấy trong mẫu thiết kế MVC.

Cám ơn bạn đã phản hồi của bạn



Đúng vậy, đó là các lớp proxy được tạo tự động mà tôi muốn. Tôi đang sử dụng các dịch vụ RESTful / RPC cho chức năng này
Sigex

Repo này chỉ dành cho các thư viện khách hàng
orellabac

Restful không hỗ trợ giao tiếp song công
dùng1034912

1

Bạn cũng có thể tự lưu trữ ASP.NET Core Web API.

<!-- SelfHosted.csproj -->
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <!-- see: https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#framework-reference -->
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.0" />
  </ItemGroup>

</Project>
// Program.cs
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;

namespace SelfHosted
{
    class Program
    {
        static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            // see: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1
            return Host.CreateDefaultBuilder(args)
                .ConfigureHostConfiguration(configHost =>
                {
                    configHost.SetBasePath(Directory.GetCurrentDirectory());
                    configHost.AddJsonFile("appsettings.json", optional: true);
                    configHost.AddEnvironmentVariables(prefix: "SelfHosted_");
                    configHost.AddCommandLine(args);
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.CaptureStartupErrors(true);
                    webBuilder.UseStartup<Startup>();
                });
        }
    }
}
// Startup.cs
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace SelfHosted
{
    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            // see: https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/web-api/index/samples/3.x
            services.AddControllers();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
// Controllers\TestController.cs
using System.Net.Mime;
using Microsoft.AspNetCore.Mvc;

namespace SelfHosted.Controllers
{
    [ApiController]
    [Produces(MediaTypeNames.Application.Json)]
    [Route("[controller]")]
    public class HelloController : SelfHostedControllerBase
    {
        [HttpGet]
        public ActionResult<string> HelloWorld() => "Hello World!";

        [HttpGet("{name}")]
        public ActionResult<string> HelloName(string name) => $"Hello {name}!";
    }
}

Asp core web api không hỗ trợ truyền thông song công trên một cổng như cách wcf làm.
user1034912

0

Hiện đã có một cổng .NET Core: https://github.com/dotnet/wcf Nó vẫn đang trong quá trình xem trước, nhưng họ đang tích cực phát triển nó.


14
Tôi tin rằng cổng này là để giao tiếp từ Core đến WCF nhưng không phải để viết WCF trong Core.
hal9000

7
Kho lưu trữ github được liên kết cho biết rõ ràng: "Kho này chứa các thư viện WCF hướng khách hàng cho phép các ứng dụng được xây dựng trên .NET Core giao tiếp với các dịch vụ WCF."
Bahaa

0

Như ngày nay, tất cả các WCFCore selfhost có sẵn đều không dễ cài đặt và sử dụng.
Tốt nhất cho HostedService nó sẽ là lựa chọn thay thế như gRPC đã chỉ ra trong câu trả lời trước và lưu ý rằng trong 1 năm có thể thay đổi nhiều thứ chắc chắn WCF chỉ được hỗ trợ trong Core như một ứng dụng khách hoạt động tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.