commit
ac4113bef1
279 changed files with 13407 additions and 3362 deletions
@ -0,0 +1,259 @@ |
|||||||
|
// Generated by the protocol buffer compiler. DO NOT EDIT! |
||||||
|
// source: helloworld.proto |
||||||
|
#pragma warning disable 1591, 0612, 3021 |
||||||
|
#region Designer generated code |
||||||
|
|
||||||
|
using pb = global::Google.Protobuf; |
||||||
|
using pbc = global::Google.Protobuf.Collections; |
||||||
|
using pbr = global::Google.Protobuf.Reflection; |
||||||
|
using scg = global::System.Collections.Generic; |
||||||
|
namespace Helloworld { |
||||||
|
|
||||||
|
/// <summary>Holder for reflection information generated from helloworld.proto</summary> |
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||||
|
public static partial class HelloworldReflection { |
||||||
|
|
||||||
|
#region Descriptor |
||||||
|
/// <summary>File descriptor for helloworld.proto</summary> |
||||||
|
public static pbr::FileDescriptor Descriptor { |
||||||
|
get { return descriptor; } |
||||||
|
} |
||||||
|
private static pbr::FileDescriptor descriptor; |
||||||
|
|
||||||
|
static HelloworldReflection() { |
||||||
|
byte[] descriptorData = global::System.Convert.FromBase64String( |
||||||
|
string.Concat( |
||||||
|
"ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", |
||||||
|
"dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", |
||||||
|
"CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", |
||||||
|
"cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4", |
||||||
|
"YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw", |
||||||
|
"cm90bzM=")); |
||||||
|
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, |
||||||
|
new pbr::FileDescriptor[] { }, |
||||||
|
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { |
||||||
|
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null), |
||||||
|
new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null) |
||||||
|
})); |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
} |
||||||
|
#region Messages |
||||||
|
/// <summary> |
||||||
|
/// The request message containing the user's name. |
||||||
|
/// </summary> |
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||||
|
public sealed partial class HelloRequest : pb::IMessage<HelloRequest> { |
||||||
|
private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest()); |
||||||
|
public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } } |
||||||
|
|
||||||
|
public static pbr::MessageDescriptor Descriptor { |
||||||
|
get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; } |
||||||
|
} |
||||||
|
|
||||||
|
pbr::MessageDescriptor pb::IMessage.Descriptor { |
||||||
|
get { return Descriptor; } |
||||||
|
} |
||||||
|
|
||||||
|
public HelloRequest() { |
||||||
|
OnConstruction(); |
||||||
|
} |
||||||
|
|
||||||
|
partial void OnConstruction(); |
||||||
|
|
||||||
|
public HelloRequest(HelloRequest other) : this() { |
||||||
|
name_ = other.name_; |
||||||
|
} |
||||||
|
|
||||||
|
public HelloRequest Clone() { |
||||||
|
return new HelloRequest(this); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>Field number for the "name" field.</summary> |
||||||
|
public const int NameFieldNumber = 1; |
||||||
|
private string name_ = ""; |
||||||
|
public string Name { |
||||||
|
get { return name_; } |
||||||
|
set { |
||||||
|
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Equals(object other) { |
||||||
|
return Equals(other as HelloRequest); |
||||||
|
} |
||||||
|
|
||||||
|
public bool Equals(HelloRequest other) { |
||||||
|
if (ReferenceEquals(other, null)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (ReferenceEquals(other, this)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (Name != other.Name) return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override int GetHashCode() { |
||||||
|
int hash = 1; |
||||||
|
if (Name.Length != 0) hash ^= Name.GetHashCode(); |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() { |
||||||
|
return pb::JsonFormatter.ToDiagnosticString(this); |
||||||
|
} |
||||||
|
|
||||||
|
public void WriteTo(pb::CodedOutputStream output) { |
||||||
|
if (Name.Length != 0) { |
||||||
|
output.WriteRawTag(10); |
||||||
|
output.WriteString(Name); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int CalculateSize() { |
||||||
|
int size = 0; |
||||||
|
if (Name.Length != 0) { |
||||||
|
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); |
||||||
|
} |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void MergeFrom(HelloRequest other) { |
||||||
|
if (other == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (other.Name.Length != 0) { |
||||||
|
Name = other.Name; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void MergeFrom(pb::CodedInputStream input) { |
||||||
|
uint tag; |
||||||
|
while ((tag = input.ReadTag()) != 0) { |
||||||
|
switch(tag) { |
||||||
|
default: |
||||||
|
input.SkipLastField(); |
||||||
|
break; |
||||||
|
case 10: { |
||||||
|
Name = input.ReadString(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// The response message containing the greetings |
||||||
|
/// </summary> |
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||||
|
public sealed partial class HelloReply : pb::IMessage<HelloReply> { |
||||||
|
private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply()); |
||||||
|
public static pb::MessageParser<HelloReply> Parser { get { return _parser; } } |
||||||
|
|
||||||
|
public static pbr::MessageDescriptor Descriptor { |
||||||
|
get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; } |
||||||
|
} |
||||||
|
|
||||||
|
pbr::MessageDescriptor pb::IMessage.Descriptor { |
||||||
|
get { return Descriptor; } |
||||||
|
} |
||||||
|
|
||||||
|
public HelloReply() { |
||||||
|
OnConstruction(); |
||||||
|
} |
||||||
|
|
||||||
|
partial void OnConstruction(); |
||||||
|
|
||||||
|
public HelloReply(HelloReply other) : this() { |
||||||
|
message_ = other.message_; |
||||||
|
} |
||||||
|
|
||||||
|
public HelloReply Clone() { |
||||||
|
return new HelloReply(this); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>Field number for the "message" field.</summary> |
||||||
|
public const int MessageFieldNumber = 1; |
||||||
|
private string message_ = ""; |
||||||
|
public string Message { |
||||||
|
get { return message_; } |
||||||
|
set { |
||||||
|
message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Equals(object other) { |
||||||
|
return Equals(other as HelloReply); |
||||||
|
} |
||||||
|
|
||||||
|
public bool Equals(HelloReply other) { |
||||||
|
if (ReferenceEquals(other, null)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
if (ReferenceEquals(other, this)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (Message != other.Message) return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override int GetHashCode() { |
||||||
|
int hash = 1; |
||||||
|
if (Message.Length != 0) hash ^= Message.GetHashCode(); |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
public override string ToString() { |
||||||
|
return pb::JsonFormatter.ToDiagnosticString(this); |
||||||
|
} |
||||||
|
|
||||||
|
public void WriteTo(pb::CodedOutputStream output) { |
||||||
|
if (Message.Length != 0) { |
||||||
|
output.WriteRawTag(10); |
||||||
|
output.WriteString(Message); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public int CalculateSize() { |
||||||
|
int size = 0; |
||||||
|
if (Message.Length != 0) { |
||||||
|
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); |
||||||
|
} |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
public void MergeFrom(HelloReply other) { |
||||||
|
if (other == null) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (other.Message.Length != 0) { |
||||||
|
Message = other.Message; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void MergeFrom(pb::CodedInputStream input) { |
||||||
|
uint tag; |
||||||
|
while ((tag = input.ReadTag()) != 0) { |
||||||
|
switch(tag) { |
||||||
|
default: |
||||||
|
input.SkipLastField(); |
||||||
|
break; |
||||||
|
case 10: { |
||||||
|
Message = input.ReadString(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endregion Designer generated code |
@ -0,0 +1,143 @@ |
|||||||
|
// Generated by the protocol buffer compiler. DO NOT EDIT! |
||||||
|
// source: helloworld.proto |
||||||
|
// Original file comments: |
||||||
|
// Copyright 2015, Google Inc. |
||||||
|
// All rights reserved. |
||||||
|
// |
||||||
|
// Redistribution and use in source and binary forms, with or without |
||||||
|
// modification, are permitted provided that the following conditions are |
||||||
|
// met: |
||||||
|
// |
||||||
|
// * Redistributions of source code must retain the above copyright |
||||||
|
// notice, this list of conditions and the following disclaimer. |
||||||
|
// * Redistributions in binary form must reproduce the above |
||||||
|
// copyright notice, this list of conditions and the following disclaimer |
||||||
|
// in the documentation and/or other materials provided with the |
||||||
|
// distribution. |
||||||
|
// * Neither the name of Google Inc. nor the names of its |
||||||
|
// contributors may be used to endorse or promote products derived from |
||||||
|
// this software without specific prior written permission. |
||||||
|
// |
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
// |
||||||
|
#region Designer generated code |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Threading; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using Grpc.Core; |
||||||
|
|
||||||
|
namespace Helloworld { |
||||||
|
/// <summary> |
||||||
|
/// The greeting service definition. |
||||||
|
/// </summary> |
||||||
|
public static class Greeter |
||||||
|
{ |
||||||
|
static readonly string __ServiceName = "helloworld.Greeter"; |
||||||
|
|
||||||
|
static readonly Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); |
||||||
|
static readonly Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); |
||||||
|
|
||||||
|
static readonly Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>( |
||||||
|
MethodType.Unary, |
||||||
|
__ServiceName, |
||||||
|
"SayHello", |
||||||
|
__Marshaller_HelloRequest, |
||||||
|
__Marshaller_HelloReply); |
||||||
|
|
||||||
|
/// <summary>Service descriptor</summary> |
||||||
|
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor |
||||||
|
{ |
||||||
|
get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; } |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>Base class for server-side implementations of Greeter</summary> |
||||||
|
public abstract class GreeterBase |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Sends a greeting |
||||||
|
/// </summary> |
||||||
|
public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context) |
||||||
|
{ |
||||||
|
throw new RpcException(new Status(StatusCode.Unimplemented, "")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>Client for Greeter</summary> |
||||||
|
public class GreeterClient : ClientBase<GreeterClient> |
||||||
|
{ |
||||||
|
/// <summary>Creates a new client for Greeter</summary> |
||||||
|
/// <param name="channel">The channel to use to make remote calls.</param> |
||||||
|
public GreeterClient(Channel channel) : base(channel) |
||||||
|
{ |
||||||
|
} |
||||||
|
/// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary> |
||||||
|
/// <param name="callInvoker">The callInvoker to use to make remote calls.</param> |
||||||
|
public GreeterClient(CallInvoker callInvoker) : base(callInvoker) |
||||||
|
{ |
||||||
|
} |
||||||
|
/// <summary>Protected parameterless constructor to allow creation of test doubles.</summary> |
||||||
|
protected GreeterClient() : base() |
||||||
|
{ |
||||||
|
} |
||||||
|
/// <summary>Protected constructor to allow creation of configured clients.</summary> |
||||||
|
/// <param name="configuration">The client configuration.</param> |
||||||
|
protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Sends a greeting |
||||||
|
/// </summary> |
||||||
|
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) |
||||||
|
{ |
||||||
|
return SayHello(request, new CallOptions(headers, deadline, cancellationToken)); |
||||||
|
} |
||||||
|
/// <summary> |
||||||
|
/// Sends a greeting |
||||||
|
/// </summary> |
||||||
|
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options) |
||||||
|
{ |
||||||
|
return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request); |
||||||
|
} |
||||||
|
/// <summary> |
||||||
|
/// Sends a greeting |
||||||
|
/// </summary> |
||||||
|
public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) |
||||||
|
{ |
||||||
|
return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken)); |
||||||
|
} |
||||||
|
/// <summary> |
||||||
|
/// Sends a greeting |
||||||
|
/// </summary> |
||||||
|
public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options) |
||||||
|
{ |
||||||
|
return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request); |
||||||
|
} |
||||||
|
protected override GreeterClient NewInstance(ClientBaseConfiguration configuration) |
||||||
|
{ |
||||||
|
return new GreeterClient(configuration); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>Creates service definition that can be registered with a server</summary> |
||||||
|
public static ServerServiceDefinition BindService(GreeterBase serviceImpl) |
||||||
|
{ |
||||||
|
return ServerServiceDefinition.CreateBuilder() |
||||||
|
.AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
#endregion |
@ -0,0 +1,22 @@ |
|||||||
|
{ |
||||||
|
"title": "Greeter", |
||||||
|
"version": "1.0.0-*", |
||||||
|
"buildOptions": { |
||||||
|
"debugType": "portable", |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"Google.Protobuf": "3.0.0-beta3", |
||||||
|
"Grpc": "1.0.0-pre1", |
||||||
|
}, |
||||||
|
"frameworks": { |
||||||
|
"net45": { |
||||||
|
"frameworkAssemblies": { |
||||||
|
"System.Runtime": "", |
||||||
|
"System.IO": "" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"Microsoft.NETCore.Platforms": "1.0.1" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
// Copyright 2015, Google Inc. |
||||||
|
// All rights reserved. |
||||||
|
// |
||||||
|
// Redistribution and use in source and binary forms, with or without |
||||||
|
// modification, are permitted provided that the following conditions are |
||||||
|
// met: |
||||||
|
// |
||||||
|
// * Redistributions of source code must retain the above copyright |
||||||
|
// notice, this list of conditions and the following disclaimer. |
||||||
|
// * Redistributions in binary form must reproduce the above |
||||||
|
// copyright notice, this list of conditions and the following disclaimer |
||||||
|
// in the documentation and/or other materials provided with the |
||||||
|
// distribution. |
||||||
|
// * Neither the name of Google Inc. nor the names of its |
||||||
|
// contributors may be used to endorse or promote products derived from |
||||||
|
// this software without specific prior written permission. |
||||||
|
// |
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
using System; |
||||||
|
using Grpc.Core; |
||||||
|
using Helloworld; |
||||||
|
|
||||||
|
namespace GreeterClient |
||||||
|
{ |
||||||
|
class Program |
||||||
|
{ |
||||||
|
public static void Main(string[] args) |
||||||
|
{ |
||||||
|
Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); |
||||||
|
|
||||||
|
var client = new Greeter.GreeterClient(channel); |
||||||
|
String user = "you"; |
||||||
|
|
||||||
|
var reply = client.SayHello(new HelloRequest { Name = user }); |
||||||
|
Console.WriteLine("Greeting: " + reply.Message); |
||||||
|
|
||||||
|
channel.ShutdownAsync().Wait(); |
||||||
|
Console.WriteLine("Press any key to exit..."); |
||||||
|
Console.ReadKey(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
{ |
||||||
|
"title": "GreeterClient", |
||||||
|
"version": "1.0.0-*", |
||||||
|
"buildOptions": { |
||||||
|
"debugType": "portable", |
||||||
|
"emitEntryPoint": "true" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"Google.Protobuf": "3.0.0-beta3", |
||||||
|
"Grpc": "1.0.0-pre1", |
||||||
|
"Greeter": { |
||||||
|
"target": "project" |
||||||
|
} |
||||||
|
}, |
||||||
|
"frameworks": { |
||||||
|
"net45": { |
||||||
|
"frameworkAssemblies": { |
||||||
|
"System.Runtime": "", |
||||||
|
"System.IO": "" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"Microsoft.NETCore.Platforms": "1.0.1" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
// Copyright 2015, Google Inc. |
||||||
|
// All rights reserved. |
||||||
|
// |
||||||
|
// Redistribution and use in source and binary forms, with or without |
||||||
|
// modification, are permitted provided that the following conditions are |
||||||
|
// met: |
||||||
|
// |
||||||
|
// * Redistributions of source code must retain the above copyright |
||||||
|
// notice, this list of conditions and the following disclaimer. |
||||||
|
// * Redistributions in binary form must reproduce the above |
||||||
|
// copyright notice, this list of conditions and the following disclaimer |
||||||
|
// in the documentation and/or other materials provided with the |
||||||
|
// distribution. |
||||||
|
// * Neither the name of Google Inc. nor the names of its |
||||||
|
// contributors may be used to endorse or promote products derived from |
||||||
|
// this software without specific prior written permission. |
||||||
|
// |
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using Grpc.Core; |
||||||
|
using Helloworld; |
||||||
|
|
||||||
|
namespace GreeterServer |
||||||
|
{ |
||||||
|
class GreeterImpl : Greeter.GreeterBase |
||||||
|
{ |
||||||
|
// Server side handler of the SayHello RPC |
||||||
|
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) |
||||||
|
{ |
||||||
|
return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Program |
||||||
|
{ |
||||||
|
const int Port = 50051; |
||||||
|
|
||||||
|
public static void Main(string[] args) |
||||||
|
{ |
||||||
|
Server server = new Server |
||||||
|
{ |
||||||
|
Services = { Greeter.BindService(new GreeterImpl()) }, |
||||||
|
Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } |
||||||
|
}; |
||||||
|
server.Start(); |
||||||
|
|
||||||
|
Console.WriteLine("Greeter server listening on port " + Port); |
||||||
|
Console.WriteLine("Press any key to stop the server..."); |
||||||
|
Console.ReadKey(); |
||||||
|
|
||||||
|
server.ShutdownAsync().Wait(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
{ |
||||||
|
"title": "GreeterServer", |
||||||
|
"version": "1.0.0-*", |
||||||
|
"buildOptions": { |
||||||
|
"debugType": "portable", |
||||||
|
"emitEntryPoint": "true" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"Google.Protobuf": "3.0.0-beta3", |
||||||
|
"Grpc": "1.0.0-pre1", |
||||||
|
"Greeter": { |
||||||
|
"target": "project" |
||||||
|
} |
||||||
|
}, |
||||||
|
"frameworks": { |
||||||
|
"net45": { |
||||||
|
"frameworkAssemblies": { |
||||||
|
"System.Runtime": "", |
||||||
|
"System.IO": "" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"Microsoft.NETCore.Platforms": "1.0.1" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
gRPC in 3 minutes (C#) |
||||||
|
======================== |
||||||
|
|
||||||
|
BACKGROUND |
||||||
|
------------- |
||||||
|
This is a different version of the helloworld example, using the dotnet sdk |
||||||
|
tools to build and run. |
||||||
|
|
||||||
|
For this sample, we've already generated the server and client stubs from [helloworld.proto][]. |
||||||
|
|
||||||
|
Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/) |
||||||
|
and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages |
||||||
|
which have been already added to the project for you. |
||||||
|
|
||||||
|
The examples in this directory target .NET 4.5 framework, as .NET Core support is |
||||||
|
currently experimental. |
||||||
|
|
||||||
|
PREREQUISITES |
||||||
|
------------- |
||||||
|
|
||||||
|
- The DotNetCore SDK cli. |
||||||
|
|
||||||
|
- The .NET 4.5 framework. |
||||||
|
|
||||||
|
Both are available to download at https://www.microsoft.com/net/download |
||||||
|
|
||||||
|
BUILD |
||||||
|
------- |
||||||
|
|
||||||
|
From the `examples/csharp/helloworld-from-cli` directory: |
||||||
|
|
||||||
|
- `dotnet restore` |
||||||
|
|
||||||
|
- `dotnet build **/project.json` (this will automatically download NuGet dependencies) |
||||||
|
|
||||||
|
Try it! |
||||||
|
------- |
||||||
|
|
||||||
|
- Run the server |
||||||
|
|
||||||
|
``` |
||||||
|
> cd GreeterServer |
||||||
|
> dotnet run |
||||||
|
``` |
||||||
|
|
||||||
|
- Run the client |
||||||
|
|
||||||
|
``` |
||||||
|
> cd GreeterClient |
||||||
|
> dotnet run |
||||||
|
``` |
||||||
|
|
||||||
|
Tutorial |
||||||
|
-------- |
||||||
|
|
||||||
|
You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][] |
||||||
|
|
||||||
|
[helloworld.proto]:../../protos/helloworld.proto |
||||||
|
[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html |
@ -1,8 +1,7 @@ |
|||||||
{ |
{ |
||||||
"name": "grpc/grpc-demo", |
"name": "grpc/grpc-demo", |
||||||
"description": "gRPC example for PHP", |
"description": "gRPC example for PHP", |
||||||
"minimum-stability": "dev", |
|
||||||
"require": { |
"require": { |
||||||
"grpc/grpc": "v0.15.2" |
"grpc/grpc": "v1.0.0", |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,6 +1,6 @@ |
|||||||
#gRPC Basics: PHP sample code |
#gRPC Basics: PHP sample code |
||||||
|
|
||||||
The files in this folder are the samples used in [gRPC Basics: PHP][], |
The files in this folder are the samples used in [gRPC Basics: PHP][], |
||||||
a detailed tutorial for using gRPC in Ruby. |
a detailed tutorial for using gRPC in PHP. |
||||||
|
|
||||||
[gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html |
[gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html |
||||||
|
@ -0,0 +1,219 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H |
||||||
|
#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H |
||||||
|
|
||||||
|
#include <grpc/impl/codegen/byte_buffer.h> |
||||||
|
#include <grpc/impl/codegen/byte_buffer_reader.h> |
||||||
|
#include <grpc/impl/codegen/slice.h> |
||||||
|
#include <grpc/impl/codegen/slice_buffer.h> |
||||||
|
#include <thrift/protocol/TBinaryProtocol.h> |
||||||
|
#include <thrift/protocol/TCompactProtocol.h> |
||||||
|
#include <thrift/protocol/TProtocolException.h> |
||||||
|
#include <thrift/transport/TBufferTransports.h> |
||||||
|
#include <thrift/transport/TTransportUtils.h> |
||||||
|
#include <boost/make_shared.hpp> |
||||||
|
#include <memory> |
||||||
|
#include <stdexcept> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
namespace apache { |
||||||
|
namespace thrift { |
||||||
|
namespace util { |
||||||
|
|
||||||
|
using apache::thrift::protocol::TBinaryProtocolT; |
||||||
|
using apache::thrift::protocol::TCompactProtocolT; |
||||||
|
using apache::thrift::protocol::TMessageType; |
||||||
|
using apache::thrift::protocol::TNetworkBigEndian; |
||||||
|
using apache::thrift::transport::TMemoryBuffer; |
||||||
|
using apache::thrift::transport::TBufferBase; |
||||||
|
using apache::thrift::transport::TTransport; |
||||||
|
|
||||||
|
template <typename Dummy, typename Protocol> |
||||||
|
class ThriftSerializer { |
||||||
|
public: |
||||||
|
ThriftSerializer() |
||||||
|
: prepared_(false), |
||||||
|
last_deserialized_(false), |
||||||
|
serialize_version_(false) {} |
||||||
|
|
||||||
|
virtual ~ThriftSerializer() {} |
||||||
|
|
||||||
|
// Serialize the passed type into the internal buffer
|
||||||
|
// and returns a pointer to internal buffer and its size
|
||||||
|
template <typename T> |
||||||
|
void Serialize(const T& fields, const uint8_t** serialized_buffer, |
||||||
|
size_t* serialized_len) { |
||||||
|
// prepare or reset buffer
|
||||||
|
if (!prepared_ || last_deserialized_) { |
||||||
|
prepare(); |
||||||
|
} else { |
||||||
|
buffer_->resetBuffer(); |
||||||
|
} |
||||||
|
last_deserialized_ = false; |
||||||
|
|
||||||
|
// if required serialize protocol version
|
||||||
|
if (serialize_version_) { |
||||||
|
protocol_->writeMessageBegin("", TMessageType(0), 0); |
||||||
|
} |
||||||
|
|
||||||
|
// serialize fields into buffer
|
||||||
|
fields.write(protocol_.get()); |
||||||
|
|
||||||
|
// write the end of message
|
||||||
|
if (serialize_version_) { |
||||||
|
protocol_->writeMessageEnd(); |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t* byte_buffer; |
||||||
|
uint32_t byte_buffer_size; |
||||||
|
buffer_->getBuffer(&byte_buffer, &byte_buffer_size); |
||||||
|
*serialized_buffer = byte_buffer; |
||||||
|
*serialized_len = byte_buffer_size; |
||||||
|
} |
||||||
|
|
||||||
|
// Serialize the passed type into the byte buffer
|
||||||
|
template <typename T> |
||||||
|
void Serialize(const T& fields, grpc_byte_buffer** bp) { |
||||||
|
const uint8_t* byte_buffer; |
||||||
|
size_t byte_buffer_size; |
||||||
|
|
||||||
|
Serialize(fields, &byte_buffer, &byte_buffer_size); |
||||||
|
|
||||||
|
gpr_slice slice = gpr_slice_from_copied_buffer( |
||||||
|
reinterpret_cast<const char*>(byte_buffer), byte_buffer_size); |
||||||
|
|
||||||
|
*bp = grpc_raw_byte_buffer_create(&slice, 1); |
||||||
|
|
||||||
|
gpr_slice_unref(slice); |
||||||
|
} |
||||||
|
|
||||||
|
// Deserialize the passed char array into the passed type, returns the number
|
||||||
|
// of bytes that have been consumed from the passed string.
|
||||||
|
template <typename T> |
||||||
|
uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) { |
||||||
|
// prepare buffer if necessary
|
||||||
|
if (!prepared_) { |
||||||
|
prepare(); |
||||||
|
} |
||||||
|
last_deserialized_ = true; |
||||||
|
|
||||||
|
// reset buffer transport
|
||||||
|
buffer_->resetBuffer(serialized_buffer, length); |
||||||
|
|
||||||
|
// read the protocol version if necessary
|
||||||
|
if (serialize_version_) { |
||||||
|
std::string name = ""; |
||||||
|
TMessageType mt = static_cast<TMessageType>(0); |
||||||
|
int32_t seq_id = 0; |
||||||
|
protocol_->readMessageBegin(name, mt, seq_id); |
||||||
|
} |
||||||
|
|
||||||
|
// deserialize buffer into fields
|
||||||
|
uint32_t len = fields->read(protocol_.get()); |
||||||
|
|
||||||
|
// read the end of message
|
||||||
|
if (serialize_version_) { |
||||||
|
protocol_->readMessageEnd(); |
||||||
|
} |
||||||
|
|
||||||
|
return len; |
||||||
|
} |
||||||
|
|
||||||
|
// Deserialize the passed byte buffer to passed type, returns the number
|
||||||
|
// of bytes consumed from byte buffer
|
||||||
|
template <typename T> |
||||||
|
uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { |
||||||
|
grpc_byte_buffer_reader reader; |
||||||
|
grpc_byte_buffer_reader_init(&reader, buffer); |
||||||
|
|
||||||
|
gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); |
||||||
|
|
||||||
|
uint32_t len = |
||||||
|
Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); |
||||||
|
|
||||||
|
gpr_slice_unref(slice); |
||||||
|
|
||||||
|
grpc_byte_buffer_reader_destroy(&reader); |
||||||
|
|
||||||
|
return len; |
||||||
|
} |
||||||
|
|
||||||
|
// set serialization version flag
|
||||||
|
void SetSerializeVersion(bool value) { serialize_version_ = value; } |
||||||
|
|
||||||
|
// Set the container size limit to deserialize
|
||||||
|
// This function should be called after buffer_ is initialized
|
||||||
|
void SetContainerSizeLimit(int32_t container_limit) { |
||||||
|
if (!prepared_) { |
||||||
|
prepare(); |
||||||
|
} |
||||||
|
protocol_->setContainerSizeLimit(container_limit); |
||||||
|
} |
||||||
|
|
||||||
|
// Set the string size limit to deserialize
|
||||||
|
// This function should be called after buffer_ is initialized
|
||||||
|
void SetStringSizeLimit(int32_t string_limit) { |
||||||
|
if (!prepared_) { |
||||||
|
prepare(); |
||||||
|
} |
||||||
|
protocol_->setStringSizeLimit(string_limit); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
bool prepared_; |
||||||
|
bool last_deserialized_; |
||||||
|
boost::shared_ptr<TMemoryBuffer> buffer_; |
||||||
|
std::shared_ptr<Protocol> protocol_; |
||||||
|
bool serialize_version_; |
||||||
|
|
||||||
|
void prepare() { |
||||||
|
buffer_ = boost::make_shared<TMemoryBuffer>(); |
||||||
|
// create a protocol for the memory buffer transport
|
||||||
|
protocol_ = std::make_shared<Protocol>(buffer_); |
||||||
|
prepared_ = true; |
||||||
|
} |
||||||
|
|
||||||
|
}; // ThriftSerializer
|
||||||
|
|
||||||
|
typedef ThriftSerializer<void, TBinaryProtocolT<TBufferBase, TNetworkBigEndian>> |
||||||
|
ThriftSerializerBinary; |
||||||
|
typedef ThriftSerializer<void, TCompactProtocolT<TBufferBase>> |
||||||
|
ThriftSerializerCompact; |
||||||
|
|
||||||
|
} // namespace util
|
||||||
|
} // namespace thrift
|
||||||
|
} // namespace apache
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,85 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H |
||||||
|
#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H |
||||||
|
|
||||||
|
#include <grpc++/impl/codegen/config.h> |
||||||
|
#include <grpc++/impl/codegen/core_codegen_interface.h> |
||||||
|
#include <grpc++/impl/codegen/serialization_traits.h> |
||||||
|
#include <grpc++/impl/codegen/status.h> |
||||||
|
#include <grpc++/impl/codegen/status_code_enum.h> |
||||||
|
#include <grpc++/impl/codegen/thrift_serializer.h> |
||||||
|
#include <grpc/impl/codegen/byte_buffer.h> |
||||||
|
#include <grpc/impl/codegen/byte_buffer_reader.h> |
||||||
|
#include <grpc/impl/codegen/slice.h> |
||||||
|
#include <grpc/impl/codegen/slice_buffer.h> |
||||||
|
#include <cstdint> |
||||||
|
#include <cstdlib> |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
|
||||||
|
using apache::thrift::util::ThriftSerializerCompact; |
||||||
|
|
||||||
|
template <class T> |
||||||
|
class SerializationTraits<T, typename std::enable_if<std::is_base_of< |
||||||
|
apache::thrift::TBase, T>::value>::type> { |
||||||
|
public: |
||||||
|
static Status Serialize(const T& msg, grpc_byte_buffer** bp, |
||||||
|
bool* own_buffer) { |
||||||
|
*own_buffer = true; |
||||||
|
|
||||||
|
ThriftSerializerCompact serializer; |
||||||
|
serializer.Serialize(msg, bp); |
||||||
|
|
||||||
|
return Status(StatusCode::OK, "ok"); |
||||||
|
} |
||||||
|
|
||||||
|
static Status Deserialize(grpc_byte_buffer* buffer, T* msg, |
||||||
|
int max_message_size) { |
||||||
|
if (!buffer) { |
||||||
|
return Status(StatusCode::INTERNAL, "No payload"); |
||||||
|
} |
||||||
|
|
||||||
|
ThriftSerializerCompact deserializer; |
||||||
|
deserializer.Deserialize(buffer, msg); |
||||||
|
|
||||||
|
grpc_byte_buffer_destroy(buffer); |
||||||
|
|
||||||
|
return Status(StatusCode::OK, "ok"); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,112 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "src/core/lib/channel/channel_stack.h" |
||||||
|
#include "src/cpp/common/channel_filter.h" |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
|
||||||
|
// MetadataBatch
|
||||||
|
|
||||||
|
grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key, |
||||||
|
const string &value) { |
||||||
|
grpc_linked_mdelem *storage = new grpc_linked_mdelem; |
||||||
|
memset(storage, 0, sizeof(grpc_linked_mdelem)); |
||||||
|
storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str()); |
||||||
|
grpc_metadata_batch_link_head(batch_, storage); |
||||||
|
return storage; |
||||||
|
} |
||||||
|
|
||||||
|
// ChannelData
|
||||||
|
|
||||||
|
void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_channel_element *elem, |
||||||
|
TransportOp *op) { |
||||||
|
grpc_channel_next_op(exec_ctx, elem, op->op()); |
||||||
|
} |
||||||
|
|
||||||
|
// CallData
|
||||||
|
|
||||||
|
void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
TransportStreamOp *op) { |
||||||
|
grpc_call_next_op(exec_ctx, elem, op->op()); |
||||||
|
} |
||||||
|
|
||||||
|
void CallData::SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
grpc_polling_entity *pollent) { |
||||||
|
grpc_call_stack_ignore_set_pollset_or_pollset_set(exec_ctx, elem, pollent); |
||||||
|
} |
||||||
|
|
||||||
|
char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { |
||||||
|
return grpc_call_next_get_peer(exec_ctx, elem); |
||||||
|
} |
||||||
|
|
||||||
|
// internal code used by RegisterChannelFilter()
|
||||||
|
|
||||||
|
namespace internal { |
||||||
|
|
||||||
|
// Note: Implicitly initialized to nullptr due to static lifetime.
|
||||||
|
std::vector<FilterRecord> *channel_filters; |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) { |
||||||
|
const FilterRecord &filter = *(FilterRecord *)arg; |
||||||
|
if (filter.include_filter) { |
||||||
|
const grpc_channel_args *args = |
||||||
|
grpc_channel_stack_builder_get_channel_arguments(builder); |
||||||
|
if (!filter.include_filter(*args)) return true; |
||||||
|
} |
||||||
|
return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter, |
||||||
|
nullptr, nullptr); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void ChannelFilterPluginInit() { |
||||||
|
for (size_t i = 0; i < channel_filters->size(); ++i) { |
||||||
|
FilterRecord &filter = (*channel_filters)[i]; |
||||||
|
grpc_channel_init_register_stage(filter.stack_type, filter.priority, |
||||||
|
MaybeAddFilter, (void *)&filter); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void ChannelFilterPluginShutdown() {} |
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace grpc
|
@ -0,0 +1,389 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2016, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPCXX_CHANNEL_FILTER_H |
||||||
|
#define GRPCXX_CHANNEL_FILTER_H |
||||||
|
|
||||||
|
#include <grpc++/impl/codegen/config.h> |
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/impl/codegen/alloc.h> |
||||||
|
|
||||||
|
#include <functional> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include "src/core/lib/channel/channel_stack.h" |
||||||
|
#include "src/core/lib/surface/channel_init.h" |
||||||
|
#include "src/core/lib/transport/metadata_batch.h" |
||||||
|
|
||||||
|
/// An interface to define filters.
|
||||||
|
///
|
||||||
|
/// To define a filter, implement a subclass of each of \c CallData and
|
||||||
|
/// \c ChannelData. Then register the filter using something like this:
|
||||||
|
/// \code{.cpp}
|
||||||
|
/// RegisterChannelFilter<MyChannelDataSubclass, MyCallDataSubclass>(
|
||||||
|
/// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr);
|
||||||
|
/// \endcode
|
||||||
|
|
||||||
|
/// Forward declaration to avoid including the file
|
||||||
|
/// "src/core/lib/security/context/security_context.h"
|
||||||
|
struct grpc_client_security_context; |
||||||
|
struct grpc_server_security_context; |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
|
||||||
|
/// A C++ wrapper for the \c grpc_metadata_batch struct.
|
||||||
|
class MetadataBatch { |
||||||
|
public: |
||||||
|
/// Borrows a pointer to \a batch, but does NOT take ownership.
|
||||||
|
/// The caller must ensure that \a batch continues to exist for as
|
||||||
|
/// long as the MetadataBatch object does.
|
||||||
|
explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {} |
||||||
|
|
||||||
|
grpc_metadata_batch *batch() const { return batch_; } |
||||||
|
|
||||||
|
/// Adds metadata and returns the newly allocated storage.
|
||||||
|
/// The caller takes ownership of the result, which must exist for the
|
||||||
|
/// lifetime of the gRPC call.
|
||||||
|
grpc_linked_mdelem *AddMetadata(const string &key, const string &value); |
||||||
|
|
||||||
|
class const_iterator : public std::iterator<std::bidirectional_iterator_tag, |
||||||
|
const grpc_mdelem> { |
||||||
|
public: |
||||||
|
const grpc_mdelem &operator*() const { return *elem_->md; } |
||||||
|
const grpc_mdelem *operator->() const { return elem_->md; } |
||||||
|
|
||||||
|
const_iterator &operator++() { |
||||||
|
elem_ = elem_->next; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
const_iterator operator++(int) { |
||||||
|
const_iterator tmp(*this); |
||||||
|
operator++(); |
||||||
|
return tmp; |
||||||
|
} |
||||||
|
const_iterator &operator--() { |
||||||
|
elem_ = elem_->prev; |
||||||
|
return *this; |
||||||
|
} |
||||||
|
const_iterator operator--(int) { |
||||||
|
const_iterator tmp(*this); |
||||||
|
operator--(); |
||||||
|
return tmp; |
||||||
|
} |
||||||
|
|
||||||
|
bool operator==(const const_iterator &other) const { |
||||||
|
return elem_ == other.elem_; |
||||||
|
} |
||||||
|
bool operator!=(const const_iterator &other) const { |
||||||
|
return elem_ != other.elem_; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
friend class MetadataBatch; |
||||||
|
explicit const_iterator(grpc_linked_mdelem *elem) : elem_(elem) {} |
||||||
|
|
||||||
|
grpc_linked_mdelem *elem_; |
||||||
|
}; |
||||||
|
|
||||||
|
const_iterator begin() const { return const_iterator(batch_->list.head); } |
||||||
|
const_iterator end() const { return const_iterator(nullptr); } |
||||||
|
|
||||||
|
private: |
||||||
|
grpc_metadata_batch *batch_; // Not owned.
|
||||||
|
}; |
||||||
|
|
||||||
|
/// A C++ wrapper for the \c grpc_transport_op struct.
|
||||||
|
class TransportOp { |
||||||
|
public: |
||||||
|
/// Borrows a pointer to \a op, but does NOT take ownership.
|
||||||
|
/// The caller must ensure that \a op continues to exist for as
|
||||||
|
/// long as the TransportOp object does.
|
||||||
|
explicit TransportOp(grpc_transport_op *op) : op_(op) {} |
||||||
|
|
||||||
|
grpc_transport_op *op() const { return op_; } |
||||||
|
|
||||||
|
// TODO(roth): Add a C++ wrapper for grpc_error?
|
||||||
|
grpc_error *disconnect_with_error() const { |
||||||
|
return op_->disconnect_with_error; |
||||||
|
} |
||||||
|
bool send_goaway() const { return op_->send_goaway; } |
||||||
|
|
||||||
|
// TODO(roth): Add methods for additional fields as needed.
|
||||||
|
|
||||||
|
private: |
||||||
|
grpc_transport_op *op_; // Not owned.
|
||||||
|
}; |
||||||
|
|
||||||
|
/// A C++ wrapper for the \c grpc_transport_stream_op struct.
|
||||||
|
class TransportStreamOp { |
||||||
|
public: |
||||||
|
/// Borrows a pointer to \a op, but does NOT take ownership.
|
||||||
|
/// The caller must ensure that \a op continues to exist for as
|
||||||
|
/// long as the TransportStreamOp object does.
|
||||||
|
explicit TransportStreamOp(grpc_transport_stream_op *op) |
||||||
|
: op_(op), |
||||||
|
send_initial_metadata_(op->send_initial_metadata), |
||||||
|
send_trailing_metadata_(op->send_trailing_metadata), |
||||||
|
recv_initial_metadata_(op->recv_initial_metadata), |
||||||
|
recv_trailing_metadata_(op->recv_trailing_metadata) {} |
||||||
|
|
||||||
|
grpc_transport_stream_op *op() const { return op_; } |
||||||
|
|
||||||
|
grpc_closure *on_complete() const { return op_->on_complete; } |
||||||
|
void set_on_complete(grpc_closure *closure) { op_->on_complete = closure; } |
||||||
|
|
||||||
|
MetadataBatch *send_initial_metadata() { |
||||||
|
return op_->send_initial_metadata == nullptr ? nullptr |
||||||
|
: &send_initial_metadata_; |
||||||
|
} |
||||||
|
MetadataBatch *send_trailing_metadata() { |
||||||
|
return op_->send_trailing_metadata == nullptr ? nullptr |
||||||
|
: &send_trailing_metadata_; |
||||||
|
} |
||||||
|
MetadataBatch *recv_initial_metadata() { |
||||||
|
return op_->recv_initial_metadata == nullptr ? nullptr |
||||||
|
: &recv_initial_metadata_; |
||||||
|
} |
||||||
|
MetadataBatch *recv_trailing_metadata() { |
||||||
|
return op_->recv_trailing_metadata == nullptr ? nullptr |
||||||
|
: &recv_trailing_metadata_; |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t *send_initial_metadata_flags() const { |
||||||
|
return &op_->send_initial_metadata_flags; |
||||||
|
} |
||||||
|
|
||||||
|
grpc_closure *recv_initial_metadata_ready() const { |
||||||
|
return op_->recv_initial_metadata_ready; |
||||||
|
} |
||||||
|
void set_recv_initial_metadata_ready(grpc_closure *closure) { |
||||||
|
op_->recv_initial_metadata_ready = closure; |
||||||
|
} |
||||||
|
|
||||||
|
grpc_byte_stream *send_message() const { return op_->send_message; } |
||||||
|
void set_send_message(grpc_byte_stream *send_message) { |
||||||
|
op_->send_message = send_message; |
||||||
|
} |
||||||
|
|
||||||
|
/// To be called only on clients and servers, respectively.
|
||||||
|
grpc_client_security_context *client_security_context() const { |
||||||
|
return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY] |
||||||
|
.value; |
||||||
|
} |
||||||
|
grpc_server_security_context *server_security_context() const { |
||||||
|
return (grpc_server_security_context *)op_->context[GRPC_CONTEXT_SECURITY] |
||||||
|
.value; |
||||||
|
} |
||||||
|
|
||||||
|
census_context *get_census_context() const { |
||||||
|
return (census_context *)op_->context[GRPC_CONTEXT_TRACING].value; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
grpc_transport_stream_op *op_; // Not owned.
|
||||||
|
MetadataBatch send_initial_metadata_; |
||||||
|
MetadataBatch send_trailing_metadata_; |
||||||
|
MetadataBatch recv_initial_metadata_; |
||||||
|
MetadataBatch recv_trailing_metadata_; |
||||||
|
}; |
||||||
|
|
||||||
|
/// Represents channel data.
|
||||||
|
class ChannelData { |
||||||
|
public: |
||||||
|
virtual ~ChannelData() { |
||||||
|
if (peer_) gpr_free((void *)peer_); |
||||||
|
} |
||||||
|
|
||||||
|
/// Caller does NOT take ownership of result.
|
||||||
|
const char *peer() const { return peer_; } |
||||||
|
|
||||||
|
// TODO(roth): Find a way to avoid passing elem into these methods.
|
||||||
|
virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_channel_element *elem, TransportOp *op); |
||||||
|
|
||||||
|
protected: |
||||||
|
/// Takes ownership of \a peer.
|
||||||
|
ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} |
||||||
|
|
||||||
|
private: |
||||||
|
const char *peer_; |
||||||
|
}; |
||||||
|
|
||||||
|
/// Represents call data.
|
||||||
|
class CallData { |
||||||
|
public: |
||||||
|
virtual ~CallData() {} |
||||||
|
|
||||||
|
/// Initializes the call data.
|
||||||
|
virtual grpc_error *Init() { return GRPC_ERROR_NONE; } |
||||||
|
|
||||||
|
// TODO(roth): Find a way to avoid passing elem into these methods.
|
||||||
|
|
||||||
|
/// Starts a new stream operation.
|
||||||
|
virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
TransportStreamOp *op); |
||||||
|
|
||||||
|
/// Sets a pollset or pollset set.
|
||||||
|
virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
grpc_polling_entity *pollent); |
||||||
|
|
||||||
|
/// Gets the peer name.
|
||||||
|
virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); |
||||||
|
|
||||||
|
protected: |
||||||
|
explicit CallData(const ChannelData &) {} |
||||||
|
}; |
||||||
|
|
||||||
|
namespace internal { |
||||||
|
|
||||||
|
// Defines static members for passing to C core.
|
||||||
|
// Members of this class correspond to the members of the C
|
||||||
|
// grpc_channel_filter struct.
|
||||||
|
template <typename ChannelDataType, typename CallDataType> |
||||||
|
class ChannelFilter GRPC_FINAL { |
||||||
|
public: |
||||||
|
static const size_t channel_data_size = sizeof(ChannelDataType); |
||||||
|
|
||||||
|
static void InitChannelElement(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_channel_element *elem, |
||||||
|
grpc_channel_element_args *args) { |
||||||
|
const char *peer = |
||||||
|
args->optional_transport |
||||||
|
? grpc_transport_get_peer(exec_ctx, args->optional_transport) |
||||||
|
: nullptr; |
||||||
|
// Construct the object in the already-allocated memory.
|
||||||
|
new (elem->channel_data) ChannelDataType(*args->channel_args, peer); |
||||||
|
} |
||||||
|
|
||||||
|
static void DestroyChannelElement(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_channel_element *elem) { |
||||||
|
reinterpret_cast<ChannelDataType *>(elem->channel_data)->~ChannelDataType(); |
||||||
|
} |
||||||
|
|
||||||
|
static void StartTransportOp(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_channel_element *elem, |
||||||
|
grpc_transport_op *op) { |
||||||
|
ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data; |
||||||
|
TransportOp op_wrapper(op); |
||||||
|
channel_data->StartTransportOp(exec_ctx, elem, &op_wrapper); |
||||||
|
} |
||||||
|
|
||||||
|
static const size_t call_data_size = sizeof(CallDataType); |
||||||
|
|
||||||
|
static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
grpc_call_element_args *args) { |
||||||
|
const ChannelDataType &channel_data = |
||||||
|
*(ChannelDataType *)elem->channel_data; |
||||||
|
// Construct the object in the already-allocated memory.
|
||||||
|
CallDataType *call_data = new (elem->call_data) CallDataType(channel_data); |
||||||
|
return call_data->Init(); |
||||||
|
} |
||||||
|
|
||||||
|
static void DestroyCallElement(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
const grpc_call_final_info *final_info, |
||||||
|
void *and_free_memory) { |
||||||
|
reinterpret_cast<CallDataType *>(elem->call_data)->~CallDataType(); |
||||||
|
} |
||||||
|
|
||||||
|
static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
grpc_transport_stream_op *op) { |
||||||
|
CallDataType *call_data = (CallDataType *)elem->call_data; |
||||||
|
TransportStreamOp op_wrapper(op); |
||||||
|
call_data->StartTransportStreamOp(exec_ctx, elem, &op_wrapper); |
||||||
|
} |
||||||
|
|
||||||
|
static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, |
||||||
|
grpc_call_element *elem, |
||||||
|
grpc_polling_entity *pollent) { |
||||||
|
CallDataType *call_data = (CallDataType *)elem->call_data; |
||||||
|
call_data->SetPollsetOrPollsetSet(exec_ctx, elem, pollent); |
||||||
|
} |
||||||
|
|
||||||
|
static char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { |
||||||
|
CallDataType *call_data = (CallDataType *)elem->call_data; |
||||||
|
return call_data->GetPeer(exec_ctx, elem); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
struct FilterRecord { |
||||||
|
grpc_channel_stack_type stack_type; |
||||||
|
int priority; |
||||||
|
std::function<bool(const grpc_channel_args &)> include_filter; |
||||||
|
grpc_channel_filter filter; |
||||||
|
}; |
||||||
|
extern std::vector<FilterRecord> *channel_filters; |
||||||
|
|
||||||
|
void ChannelFilterPluginInit(); |
||||||
|
void ChannelFilterPluginShutdown(); |
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// Registers a new filter.
|
||||||
|
/// Must be called by only one thread at a time.
|
||||||
|
/// The \a include_filter argument specifies a function that will be called
|
||||||
|
/// to determine at run-time whether or not to add the filter. If the
|
||||||
|
/// value is nullptr, the filter will be added unconditionally.
|
||||||
|
template <typename ChannelDataType, typename CallDataType> |
||||||
|
void RegisterChannelFilter( |
||||||
|
const char *name, grpc_channel_stack_type stack_type, int priority, |
||||||
|
std::function<bool(const grpc_channel_args &)> include_filter) { |
||||||
|
// If we haven't been called before, initialize channel_filters and
|
||||||
|
// call grpc_register_plugin().
|
||||||
|
if (internal::channel_filters == nullptr) { |
||||||
|
grpc_register_plugin(internal::ChannelFilterPluginInit, |
||||||
|
internal::ChannelFilterPluginShutdown); |
||||||
|
internal::channel_filters = new std::vector<internal::FilterRecord>(); |
||||||
|
} |
||||||
|
// Add an entry to channel_filters. The filter will be added when the
|
||||||
|
// C-core initialization code calls ChannelFilterPluginInit().
|
||||||
|
typedef internal::ChannelFilter<ChannelDataType, CallDataType> FilterType; |
||||||
|
internal::FilterRecord filter_record = { |
||||||
|
stack_type, |
||||||
|
priority, |
||||||
|
include_filter, |
||||||
|
{FilterType::StartTransportStreamOp, FilterType::StartTransportOp, |
||||||
|
FilterType::call_data_size, FilterType::InitCallElement, |
||||||
|
FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement, |
||||||
|
FilterType::channel_data_size, FilterType::InitChannelElement, |
||||||
|
FilterType::DestroyChannelElement, FilterType::GetPeer, name}}; |
||||||
|
internal::channel_filters->push_back(filter_record); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPCXX_CHANNEL_FILTER_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue