web-dev-qa-db-ja.com

.Net CoreのWCFに置き換わるものは何ですか?

.Net Frameworkコンソールアプリケーションを作成し、Add(int x, int y)関数をクラスライブラリ(.Net Framework)を使用してゼロからWCFサービス経由で公開することに慣れています。次に、コンソールアプリケーションを使用して、サーバー内でこの関数をプロキシ呼び出しします。

ただし、コンソールアプリ(.Net Core)とクラスライブラリ(.Net Core)を使用する場合、System.ServiceModelは使用できません。私はいくつかのグーグルを行いましたが、このインスタンスでWCFを「置き換える」ものがわかりませんでした。

クラスライブラリ内のAdd(int x, int y)関数をすべて.Net Core内のコンソールアプリケーションに公開するにはどうすればよいですか? System.ServiceModel.Webが表示されますが、これはクロスプラットフォームにしようとしているので、RESTfulサービスを作成する必要がありますか?

44
Sigex

WCFはWindows固有のテクノロジーであるため、.NET Coreはクロスプラットフォームであると想定されているため、.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));
20
Jacques Kang

.NETコアアプリケーション内でWebサービスをホストするためにgRPCを使用できます。

enter image description here

はじめに

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

クライアントコード

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

出力

クライアント出力のサンプル

サーバー出力のサンプル

参考文献

  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
29
Gopi

Microsoftサポートのある.NET Foundationによって維持されるCore WCFプロジェクトがあるようです。詳細はこちら: https://www.dotnetfoundation.org/blog/2019/06/07/welcoming-core-wcf-to-the-net-foundation

最初は、netTcpおよびhttpトランスポートのみが実装されます。

11

私の研究から、最良のソリューションには自動生成されたプロキシクラスがありません。この最適なソリューションは、RESTfulサービスを作成し、応答本文をモデルオブジェクトにシリアル化することです。ここで、モデルは、MVCデザインパターンにある通常のモデルオブジェクトです。

ご回答ありがとうございます

3
Sigex

利用可能な.NET Coreポートがあります。 https://github.com/dotnet/wcf まだプレビュー中ですが、積極的に開発中です。

0
Flupp