diff --git a/README.md b/README.md index a7111981a45..a12110d7cda 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ You can find quick start guides for each language, including installation instru * [Node.js](https://github.com/grpc/grpc-common/tree/master/node) * [Android Java](https://github.com/grpc/grpc-common/tree/master/java/android) * [Python](https://github.com/grpc/grpc-common/tree/master/python/helloworld) +* [C#](https://github.com/grpc/grpc-common/tree/master/csharp) ## What's in this repository? diff --git a/csharp/.gitignore b/csharp/.gitignore new file mode 100644 index 00000000000..585000ea2d5 --- /dev/null +++ b/csharp/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +packages/ +*.suo +*.userprefs diff --git a/csharp/Greeter.sln b/csharp/Greeter.sln new file mode 100644 index 00000000000..03f18878075 --- /dev/null +++ b/csharp/Greeter.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = Greeter\Greeter.csproj + EndGlobalSection +EndGlobal diff --git a/csharp/Greeter/.gitignore b/csharp/Greeter/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/csharp/Greeter/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/csharp/Greeter/Greeter.csproj b/csharp/Greeter/Greeter.csproj new file mode 100644 index 00000000000..5291ff0ed91 --- /dev/null +++ b/csharp/Greeter/Greeter.csproj @@ -0,0 +1,78 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Library + Greeter + Greeter + v4.5 + ab4401aa + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + false + + + full + true + bin\Release + prompt + 4 + false + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.5.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/Greeter/Helloworld.cs b/csharp/Greeter/Helloworld.cs new file mode 100644 index 00000000000..923a4271e98 --- /dev/null +++ b/csharp/Greeter/Helloworld.cs @@ -0,0 +1,617 @@ +// 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.ProtocolBuffers; +using pbc = global::Google.ProtocolBuffers.Collections; +using pbd = global::Google.ProtocolBuffers.Descriptors; +using scg = global::System.Collections.Generic; +namespace helloworld { + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class Helloworld { + + #region Extension registration + public static void RegisterAllExtensions(pb::ExtensionRegistry registry) { + } + #endregion + #region Static variables + internal static pbd::MessageDescriptor internal__static_helloworld_HelloRequest__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloRequest__FieldAccessorTable; + internal static pbd::MessageDescriptor internal__static_helloworld_HelloReply__Descriptor; + internal static pb::FieldAccess.FieldAccessorTable internal__static_helloworld_HelloReply__FieldAccessorTable; + #endregion + #region Descriptor + public static pbd::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbd::FileDescriptor descriptor; + + static Helloworld() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", + "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", + "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", + "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEISChBpby5ncnBjLmV4", + "YW1wbGVz")); + pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) { + descriptor = root; + internal__static_helloworld_HelloRequest__Descriptor = Descriptor.MessageTypes[0]; + internal__static_helloworld_HelloRequest__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloRequest__Descriptor, + new string[] { "Name", }); + internal__static_helloworld_HelloReply__Descriptor = Descriptor.MessageTypes[1]; + internal__static_helloworld_HelloReply__FieldAccessorTable = + new pb::FieldAccess.FieldAccessorTable(internal__static_helloworld_HelloReply__Descriptor, + new string[] { "Message", }); + pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance(); + RegisterAllExtensions(registry); + return registry; + }; + pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData, + new pbd::FileDescriptor[] { + }, assigner); + } + #endregion + + } + #region Messages + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloRequest : pb::GeneratedMessage { + private HelloRequest() { } + private static readonly HelloRequest defaultInstance = new HelloRequest().MakeReadOnly(); + private static readonly string[] _helloRequestFieldNames = new string[] { "name" }; + private static readonly uint[] _helloRequestFieldTags = new uint[] { 10 }; + public static HelloRequest DefaultInstance { + get { return defaultInstance; } + } + + public override HelloRequest DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override HelloRequest ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloRequest__FieldAccessorTable; } + } + + public const int NameFieldNumber = 1; + private bool hasName; + private string name_ = ""; + public bool HasName { + get { return hasName; } + } + public string Name { + get { return name_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _helloRequestFieldNames; + if (hasName) { + output.WriteString(1, field_names[0], Name); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasName) { + size += pb::CodedOutputStream.ComputeStringSize(1, Name); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static HelloRequest ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static HelloRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private HelloRequest MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(HelloRequest prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(HelloRequest cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private HelloRequest result; + + private HelloRequest PrepareBuilder() { + if (resultIsReadOnly) { + HelloRequest original = result; + result = new HelloRequest(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override HelloRequest MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::helloworld.HelloRequest.Descriptor; } + } + + public override HelloRequest DefaultInstanceForType { + get { return global::helloworld.HelloRequest.DefaultInstance; } + } + + public override HelloRequest BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is HelloRequest) { + return MergeFrom((HelloRequest) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(HelloRequest other) { + if (other == global::helloworld.HelloRequest.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasName) { + Name = other.Name; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_helloRequestFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _helloRequestFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasName = input.ReadString(ref result.name_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasName { + get { return result.hasName; } + } + public string Name { + get { return result.Name; } + set { SetName(value); } + } + public Builder SetName(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasName = true; + result.name_ = value; + return this; + } + public Builder ClearName() { + PrepareBuilder(); + result.hasName = false; + result.name_ = ""; + return this; + } + } + static HelloRequest() { + object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloReply : pb::GeneratedMessage { + private HelloReply() { } + private static readonly HelloReply defaultInstance = new HelloReply().MakeReadOnly(); + private static readonly string[] _helloReplyFieldNames = new string[] { "message" }; + private static readonly uint[] _helloReplyFieldTags = new uint[] { 10 }; + public static HelloReply DefaultInstance { + get { return defaultInstance; } + } + + public override HelloReply DefaultInstanceForType { + get { return DefaultInstance; } + } + + protected override HelloReply ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::helloworld.Helloworld.internal__static_helloworld_HelloReply__FieldAccessorTable; } + } + + public const int MessageFieldNumber = 1; + private bool hasMessage; + private string message_ = ""; + public bool HasMessage { + get { return hasMessage; } + } + public string Message { + get { return message_; } + } + + public override bool IsInitialized { + get { + return true; + } + } + + public override void WriteTo(pb::ICodedOutputStream output) { + CalcSerializedSize(); + string[] field_names = _helloReplyFieldNames; + if (hasMessage) { + output.WriteString(1, field_names[0], Message); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + return CalcSerializedSize(); + } + } + + private int CalcSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (hasMessage) { + size += pb::CodedOutputStream.ComputeStringSize(1, Message); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + public static HelloReply ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static HelloReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input) { + return CreateBuilder().MergeDelimitedFrom(input).BuildParsed(); + } + public static HelloReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ICodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static HelloReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + private HelloReply MakeReadOnly() { + return this; + } + + public static Builder CreateBuilder() { return new Builder(); } + public override Builder ToBuilder() { return CreateBuilder(this); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(HelloReply prototype) { + return new Builder(prototype); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() { + result = DefaultInstance; + resultIsReadOnly = true; + } + internal Builder(HelloReply cloneFrom) { + result = cloneFrom; + resultIsReadOnly = true; + } + + private bool resultIsReadOnly; + private HelloReply result; + + private HelloReply PrepareBuilder() { + if (resultIsReadOnly) { + HelloReply original = result; + result = new HelloReply(); + resultIsReadOnly = false; + MergeFrom(original); + } + return result; + } + + public override bool IsInitialized { + get { return result.IsInitialized; } + } + + protected override HelloReply MessageBeingBuilt { + get { return PrepareBuilder(); } + } + + public override Builder Clear() { + result = DefaultInstance; + resultIsReadOnly = true; + return this; + } + + public override Builder Clone() { + if (resultIsReadOnly) { + return new Builder(result); + } else { + return new Builder().MergeFrom(result); + } + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return global::helloworld.HelloReply.Descriptor; } + } + + public override HelloReply DefaultInstanceForType { + get { return global::helloworld.HelloReply.DefaultInstance; } + } + + public override HelloReply BuildPartial() { + if (resultIsReadOnly) { + return result; + } + resultIsReadOnly = true; + return result.MakeReadOnly(); + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is HelloReply) { + return MergeFrom((HelloReply) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(HelloReply other) { + if (other == global::helloworld.HelloReply.DefaultInstance) return this; + PrepareBuilder(); + if (other.HasMessage) { + Message = other.Message; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::ICodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + PrepareBuilder(); + pb::UnknownFieldSet.Builder unknownFields = null; + uint tag; + string field_name; + while (input.ReadTag(out tag, out field_name)) { + if(tag == 0 && field_name != null) { + int field_ordinal = global::System.Array.BinarySearch(_helloReplyFieldNames, field_name, global::System.StringComparer.Ordinal); + if(field_ordinal >= 0) + tag = _helloReplyFieldTags[field_ordinal]; + else { + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + continue; + } + } + switch (tag) { + case 0: { + throw pb::InvalidProtocolBufferException.InvalidTag(); + } + default: { + if (pb::WireFormat.IsEndGroupTag(tag)) { + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + if (unknownFields == null) { + unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + } + ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name); + break; + } + case 10: { + result.hasMessage = input.ReadString(ref result.message_); + break; + } + } + } + + if (unknownFields != null) { + this.UnknownFields = unknownFields.Build(); + } + return this; + } + + + public bool HasMessage { + get { return result.hasMessage; } + } + public string Message { + get { return result.Message; } + set { SetMessage(value); } + } + public Builder SetMessage(string value) { + pb::ThrowHelper.ThrowIfNull(value, "value"); + PrepareBuilder(); + result.hasMessage = true; + result.message_ = value; + return this; + } + public Builder ClearMessage() { + PrepareBuilder(); + result.hasMessage = false; + result.message_ = ""; + return this; + } + } + static HelloReply() { + object.ReferenceEquals(global::helloworld.Helloworld.Descriptor, null); + } + } + + #endregion + +} + +#endregion Designer generated code diff --git a/csharp/Greeter/HelloworldGrpc.cs b/csharp/Greeter/HelloworldGrpc.cs new file mode 100644 index 00000000000..568d1d9fab4 --- /dev/null +++ b/csharp/Greeter/HelloworldGrpc.cs @@ -0,0 +1,78 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace helloworld { + public static class Greeter + { + static readonly string __ServiceName = "helloworld.Greeter"; + + static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => arg.ToByteArray(), HelloRequest.ParseFrom); + static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => arg.ToByteArray(), HelloReply.ParseFrom); + + static readonly Method __Method_SayHello = new Method( + MethodType.Unary, + "SayHello", + __Marshaller_HelloRequest, + __Marshaller_HelloReply); + + // client-side stub interface + public interface IGreeterClient + { + HelloReply SayHello(HelloRequest request, CancellationToken token = default(CancellationToken)); + Task SayHelloAsync(HelloRequest request, CancellationToken token = default(CancellationToken)); + } + + // server-side interface + public interface IGreeter + { + Task SayHello(ServerCallContext context, HelloRequest request); + } + + // client stub + public class GreeterClient : AbstractStub, IGreeterClient + { + public GreeterClient(Channel channel) : this(channel, StubConfiguration.Default) + { + } + public GreeterClient(Channel channel, StubConfiguration config) : base(channel, config) + { + } + public HelloReply SayHello(HelloRequest request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_SayHello); + return Calls.BlockingUnaryCall(call, request, token); + } + public Task SayHelloAsync(HelloRequest request, CancellationToken token = default(CancellationToken)) + { + var call = CreateCall(__ServiceName, __Method_SayHello); + return Calls.AsyncUnaryCall(call, request, token); + } + } + + // creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(IGreeter serviceImpl) + { + return ServerServiceDefinition.CreateBuilder(__ServiceName) + .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); + } + + // creates a new client stub + public static IGreeterClient NewStub(Channel channel) + { + return new GreeterClient(channel); + } + + // creates a new client stub + public static IGreeterClient NewStub(Channel channel, StubConfiguration config) + { + return new GreeterClient(channel, config); + } + } +} +#endregion diff --git a/csharp/Greeter/Properties/AssemblyInfo.cs b/csharp/Greeter/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..b9d0dc264d5 --- /dev/null +++ b/csharp/Greeter/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("Greeter")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/csharp/Greeter/packages.config b/csharp/Greeter/packages.config new file mode 100644 index 00000000000..ee709c28761 --- /dev/null +++ b/csharp/Greeter/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/csharp/Greeter/protos/helloworld.proto b/csharp/Greeter/protos/helloworld.proto new file mode 100644 index 00000000000..e02ebd94e7c --- /dev/null +++ b/csharp/Greeter/protos/helloworld.proto @@ -0,0 +1,52 @@ +// 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. + +// TODO(jtattermusch): as of now, C# protobufs don't officially support +// proto3. +syntax = "proto2"; + +option java_package = "io.grpc.examples"; + +package helloworld; + +// The greeting service definition. +service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +// The request message containing the user's name. +message HelloRequest { + optional string name = 1; +} + +// The response message containing the greetings +message HelloReply { + optional string message = 1; +} diff --git a/csharp/GreeterClient/.gitignore b/csharp/GreeterClient/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/csharp/GreeterClient/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/csharp/GreeterClient/GreeterClient.csproj b/csharp/GreeterClient/GreeterClient.csproj new file mode 100644 index 00000000000..36a8578d054 --- /dev/null +++ b/csharp/GreeterClient/GreeterClient.csproj @@ -0,0 +1,81 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {ACCF4597-3748-4117-8633-1CB767F8CCC3} + Exe + GreeterClient + GreeterClient + v4.5 + 7441d94c + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.5.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + + + + + + + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Greeter + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/GreeterClient/Program.cs b/csharp/GreeterClient/Program.cs new file mode 100644 index 00000000000..61c29762b12 --- /dev/null +++ b/csharp/GreeterClient/Program.cs @@ -0,0 +1,25 @@ +using System; +using Grpc.Core; +using helloworld; + +namespace GreeterClient +{ + class ClientMainClass + { + public static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + using (Channel channel = new Channel("127.0.0.1:50051")) + { + var client = Greeter.NewStub(channel); + String user = "you"; + + var reply = client.SayHello(new HelloRequest.Builder { Name = user }.Build()); + Console.WriteLine("Greeting: " + reply.Message); + } + + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/csharp/GreeterClient/Properties/AssemblyInfo.cs b/csharp/GreeterClient/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..1422e952d8b --- /dev/null +++ b/csharp/GreeterClient/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("GreeterClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/csharp/GreeterClient/packages.config b/csharp/GreeterClient/packages.config new file mode 100644 index 00000000000..ee709c28761 --- /dev/null +++ b/csharp/GreeterClient/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/csharp/GreeterServer/.gitignore b/csharp/GreeterServer/.gitignore new file mode 100644 index 00000000000..1746e3269ed --- /dev/null +++ b/csharp/GreeterServer/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/csharp/GreeterServer/GreeterServer.csproj b/csharp/GreeterServer/GreeterServer.csproj new file mode 100644 index 00000000000..7aef52b156c --- /dev/null +++ b/csharp/GreeterServer/GreeterServer.csproj @@ -0,0 +1,81 @@ + + + + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {A7706C84-92D2-4B7A-B779-76B64D2950EC} + Exe + GreeterServer + GreeterServer + v4.5 + 12de73cb + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + true + + + full + true + bin\Release + prompt + 4 + true + + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll + + + ..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll + + + False + ..\packages\Grpc.Core.0.5.0\lib\net45\Grpc.Core.dll + + + + False + ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + + + + + + + + + {724DFC8C-4B57-4C3F-811C-0463BE2A2829} + Greeter + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/GreeterServer/Program.cs b/csharp/GreeterServer/Program.cs new file mode 100644 index 00000000000..9482797c3b9 --- /dev/null +++ b/csharp/GreeterServer/Program.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Grpc.Core; +using helloworld; + +namespace GreeterServer +{ + class GreeterImpl : Greeter.IGreeter + { + // Server side handler of the SayHello RPC + public Task SayHello(ServerCallContext context, HelloRequest request) + { + var reply = new HelloReply.Builder { Message = "Hello " + request.Name }.Build(); + return Task.FromResult(reply); + } + } + + class ServerMainClass + { + public static void Main(string[] args) + { + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(Greeter.BindService(new GreeterImpl())); + int port = server.AddListeningPort("localhost", 50051); + server.Start(); + + Console.WriteLine("Greeter server listening on port " + port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/csharp/GreeterServer/Properties/AssemblyInfo.cs b/csharp/GreeterServer/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..f8a8d521d85 --- /dev/null +++ b/csharp/GreeterServer/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. +[assembly: AssemblyTitle("GreeterServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("jtattermusch")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. +[assembly: AssemblyVersion("1.0.*")] +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/csharp/GreeterServer/packages.config b/csharp/GreeterServer/packages.config new file mode 100644 index 00000000000..ee709c28761 --- /dev/null +++ b/csharp/GreeterServer/packages.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/csharp/README.md b/csharp/README.md new file mode 100644 index 00000000000..438bdff152f --- /dev/null +++ b/csharp/README.md @@ -0,0 +1,60 @@ +gRPC in 3 minutes (C#) +======================== + +BACKGROUND +------------- +For this sample, we've already generated the server and client stubs from `helloworld.proto`. +Example projects depend on NuGet packages `Grpc` and `Google.ProtocolBuffers` which have been already added to the project for you. + +PREREQUISITES +------------- +Windows +- .NET 4.5+ +- VS 2013 (with NuGet plugin installed) + +Linux (Mono) +- Mono installed +- Monodevelop 5.9 with NuGet Add-in installed (older versions might work) + +MacOS (Mono) +- TODO: MacOS support in progress +- Xamarin Studio (with NuGet plugin installed) + +BUILD +------- + +Windows +- Clone this repository. +- Open solution `Greeter.sln` with Visual Studio +- Build the solution (this will automatically download NuGet dependencies) + +Linux (Mono) +- Clone this repository. +- Install gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc +- TODO: explain using LD_LIBRARY_PATH or installation to /usr/local +- Open solution `Greeter.sln` in MonoDevelop (you need to manually restore dependencies by using `mono nuget.exe restore` if you don't have NuGet add-in) +- Build the solution. + +Try it! +------- + +- Run the server +``` +> cd GreeterServer/bin/Debug +> GreeterServer.exe +``` + +- Run the client +``` +> cd GreeterClient/bin/Debug +> GreeterClient.exe +``` + +You can also run the server and client directly from Visual Studio. + +On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to run the server and client. + +Tutorial +-------- + +You can find a more detailed tutorial in [gRPC Basics: C#](https://github.com/grpc/grpc-common/blob/master/csharp/route_guide/README.md)