Giter VIP home page Giter VIP logo

magiconion's People

Contributors

0x5143 avatar alfeg avatar bamchoh avatar bearpro avatar caib avatar carlosxie avatar daniilsokolyuk avatar dependabot[bot] avatar doyasu24 avatar g2-nagasaki-shota avatar gavar avatar github-actions[bot] avatar gnicojp avatar guitarrapc avatar h-shn-k avatar hankovich avatar honda-tatsuya avatar itn3000 avatar masujimaryohei avatar mayuki avatar moreal avatar neppure avatar neuecc avatar real-zony avatar taigacon avatar taketoriokina avatar veyronsakai avatar vivilily avatar xin9le avatar yucchiy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

magiconion's Issues

gRPC server host in Unity 5

Hi Neuecc,
I've been studying your UnityClient and the MagicUnion & MessagePack lib. They are awesome!
I have the grpc client hosted from a Unity 5 game (.Net 3.5) and it works great.
I have tried to host a grpc server from a Unity 5 game (.Net 3.5) and wonder if it is possible with your plugin libraries? Please, give your advises.
If it is possible, would you please give a basic instructions or guide lines or so. Very much appreciate it.
Thanks Neuecc.

Moc.exe does not work correctly

Hello,

I've faced an issue with the utile moc.exe. On its launch, with specified path to Sandbox.ConsoleServerDefinition.csproj there is generated file, that contain the following:
`
#pragma warning disable 618
#pragma warning disable 612
#pragma warning disable 414
#pragma warning disable 168
namespace MagicOnion
{
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::MagicOnion;
using global::MagicOnion.Client;

public static partial class MagicOnionInitializer
{
    static bool isRegistered = false;

    [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.BeforeSceneLoad)]
    public static void Register()
    {
        if(isRegistered) return;
        isRegistered = true;

    }
}

}
#pragma warning disable 618
#pragma warning disable 612
#pragma warning disable 414
#pragma warning disable 168

namespace MagicOnion.Resolvers
{
using System;
using MessagePack;

public class MagicOnionResolver : global::MessagePack.IFormatterResolver
{
    public static readonly global::MessagePack.IFormatterResolver Instance = new MagicOnionResolver();

    MagicOnionResolver()
    {

    }

    public global::MessagePack.Formatters.IMessagePackFormatter<T> GetFormatter<T>()
    {
        return FormatterCache<T>.formatter;
    }

    static class FormatterCache<T>
    {
        public static readonly global::MessagePack.Formatters.IMessagePackFormatter<T> formatter;

        static FormatterCache()
        {
            var f = MagicOnionResolverGetFormatterHelper.GetFormatter(typeof(T));
            if (f != null)
            {
                formatter = (global::MessagePack.Formatters.IMessagePackFormatter<T>)f;
            }
        }
    }
}

internal static class MagicOnionResolverGetFormatterHelper
{
    static readonly global::System.Collections.Generic.Dictionary<Type, int> lookup;

    static MagicOnionResolverGetFormatterHelper()
    {
        lookup = new global::System.Collections.Generic.Dictionary<Type, int>(0)
        {
        };
    }

    internal static object GetFormatter(Type t)
    {
        int key;
        if (!lookup.TryGetValue(t, out key))
        {
            if (t == typeof(UniRx.Unit))
            {
                return MagicOnion.Resolvers.UniRxIntegrate.UnitFormatter.Instance;
            }
            else if (t == typeof(Nullable<UniRx.Unit>))
            {
                return MagicOnion.Resolvers.UniRxIntegrate.NullableUnitFormatter.Instance;
            }
            return null;
        }

        switch (key)
        {
            default: return null;
        }
    }
}

}

namespace MagicOnion.Resolvers.UniRxIntegrate
{
using System;
using UniRx;
using MessagePack;
using MessagePack.Formatters;

public class UnitFormatter : IMessagePackFormatter<Unit>
{
    public static readonly IMessagePackFormatter<Unit> Instance = new UnitFormatter();

    UnitFormatter()
    {

    }

    public int Serialize(ref byte[] bytes, int offset, Unit value, IFormatterResolver typeResolver)
    {
        return MessagePackBinary.WriteNil(ref bytes, offset);
    }

    public Unit Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
    {
        if (bytes[offset] == MessagePackCode.Nil)
        {
            readSize = 1;
            return Unit.Default;
        }
        else
        {
            throw new InvalidOperationException(string.Format("code is invalid. code:{0} format:{1}", bytes[offset], MessagePackCode.ToFormatName(bytes[offset])));
        }
    }
}

public class NullableUnitFormatter : IMessagePackFormatter<Unit?>
{
    public static readonly IMessagePackFormatter<Unit?> Instance = new NullableUnitFormatter();

    NullableUnitFormatter()
    {

    }

    public int Serialize(ref byte[] bytes, int offset, Unit? value, IFormatterResolver typeResolver)
    {
        return MessagePackBinary.WriteNil(ref bytes, offset);
    }

    public Unit? Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
    {
        if (bytes[offset] == MessagePackCode.Nil)
        {
            readSize = 1;
            return Unit.Default;
        }
        else
        {
            throw new InvalidOperationException(string.Format("code is invalid. code:{0} format:{1}", bytes[offset], MessagePackCode.ToFormatName(bytes[offset])));
        }
    }
}

}

#pragma warning disable 168
#pragma warning restore 414
#pragma warning restore 618
#pragma warning restore 612
`
So there is no declaration or implementation for interfaces that present in MagicOnionGenerated.cs

Could you please advise on how to use the utile moc.exe? If possible, on the example of your project so that it was clear which paths should be specified and so on.

IOS: Symbol not found: _grpcsharp_redirect_log

Hi,
I have tried to run it in IOS and it fails with
dyld: lazy symbol binding failed: Symbol not found: _grpcsharp_redirect_log

in that function:

// System.Void Grpc.Core.Internal.NativeMethods/Delegates/grpcsharp_redirect_log_delegate::Invoke(Grpc.Core.Internal.GprLogDelegate)
extern "C"  void grpcsharp_redirect_log_delegate_Invoke_m3963642216 (grpcsharp_redirect_log_delegate_t2162057115 * __this, GprLogDelegate_t430330606 * ___callback0, const MethodInfo* method)
{
	if(__this->get_prev_9() != NULL)
	{
		grpcsharp_redirect_log_delegate_Invoke_m3963642216((grpcsharp_redirect_log_delegate_t2162057115 *)__this->get_prev_9(),___callback0, method);
	}
	il2cpp_codegen_raise_execution_engine_exception_if_method_is_not_found((MethodInfo*)(__this->get_method_3().get_m_value_0()));
	bool ___methodIsStatic = MethodIsStatic((MethodInfo*)(__this->get_method_3().get_m_value_0()));
	if (__this->get_m_target_2() != NULL && ___methodIsStatic)
	{
		typedef void (*FunctionPointerType) (Il2CppObject *, void* __this, GprLogDelegate_t430330606 * ___callback0, const MethodInfo* method);
		((FunctionPointerType)__this->get_method_ptr_0())(NULL,__this->get_m_target_2(),___callback0,(MethodInfo*)(__this->get_method_3().get_m_value_0()));
	}
	else if (__this->get_m_target_2() != NULL || ___methodIsStatic)
	{
		typedef void (*FunctionPointerType) (void* __this, GprLogDelegate_t430330606 * ___callback0, const MethodInfo* method);
		((FunctionPointerType)__this->get_method_ptr_0())(__this->get_m_target_2(),___callback0,(MethodInfo*)(__this->get_method_3().get_m_value_0()));
	}
	else
	{
		typedef void (*FunctionPointerType) (void* __this, const MethodInfo* method);
		((FunctionPointerType)__this->get_method_ptr_0())(___callback0,(MethodInfo*)(__this->get_method_3().get_m_value_0()));
	}
}

I wonder if I hasn't done some magic configuration on the Native dlls or something, but gRPC/Native/iOS/libgrpc_csharp_ext.a and others there are configured to be included in IOS build...

Error sending from server

MagicOnion.Server.StreamingContextRepository1.<WriteAsync>d__121.MoveNext() ,
Error sending from server

[Info]Working MagicOnion in production environment.

My company's new game - https://kuro-kishi.jp/ released in iOS/Android market on 28th, April.

Currently it receives 15,000 connections at peak time and it is growing.
Our system has two roles.

  • Service - Unary API Service/Realtime notification, with Redis pubsub backend
  • BattleEngine - Inmemory battle logic server, it is MORPG's playground(1~8 players per field).

We're monitoring application metrics by Datadog.
I've created Datadog C# Client.
https://github.com/neuecc/DatadogSharp

image

image

I'll talk about this architecture at AWS Summit Tokyo 2017 on 2017-05-30~06-02.
http://www.awssummit.tokyo/
When talk is done, I'll upload translated presenation slide.

And of course, I will start working on .NET Standard and other improvements.

how could I implement a interceptor at client

I want to do some backoff stratergies at client, but it's confused me without a client interceptor, can you give some advice for implementing a client interceptor or any other ideas? thanks.

Deployment

Hi,
Whats the preferred way to host Server? Can IIS be used to host MagicOnion Server or whats the preferred way.

Thanks

Can't connect to ChatService from Unity client

Hello. I am getting following exception when trying to connect to ChatService from Unity.
W1124 14:14:23.639783 Grpc.Core.Server Exception while handling RPC. System.IO.IOException: Error sending status from server.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:151
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00037] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:447
at Grpc.Core.Internal.DuplexStreamingServerCallHandler`2+d__4[TRequest,TResponse].MoveNext () [0x00205] in <5ea8f8f676f3446d845f0b8ab846a51f>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:151
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00037] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable+ConfiguredTaskAwaiter.GetResult () [0x00000] in /private/tmp/source-mono-d15-3/bockbuild-d15-3/profiles/mono-mac-xamarin/build-root/mono-x64/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:447

At the same time console chat client from sandbox connects to server without issues. Can you give any advice on this?

.NET Core

Is MagicOnion technically not able to run on .NET Core ( or the 2.0 beta )?

Service hot update

I'm using LightNode in my previous project (thanks again!). By adding following code into LightNodeServerMiddleware.cs, I was able to update the handler assembly during runtime

image

I wonder if there's any similar approach in MagicOnion.

Separate gRPC

Hi,
I was wondering if you can separate "gRPC for unity" part from MagicOnion as standalone github project. There is definitely a need for strong client side gRPC library for unity and yours is the only one that I've found.
I was planning to use only gRPC part so if it was standalone I would be able to contribute pull requests with potential bugfixes or help with upgrading to 1.1 etc
In any way thank you for lots of great high quality libraries around unity and dotnet core πŸ‘

Grpc.Core.RpcException:β€œStatus(StatusCode=Unimplemented, Detail="")”

When I implements IService In single Library, Then will throw a exception like issue title.
but I implements it in Server project. It's Successful.
I read souce code ,then find this code:
( code in MagicOnionEngine.cs of line 40)

    /// <summary>
    /// Search MagicOnion service from entry assembly.
    /// </summary>
    public static MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options)
    {
        return BuildServerServiceDefinition(new[] { Assembly.GetEntryAssembly() }, options);
    }

I think you'd better change Assembly.GetEntryAssembly to Assembly.GetExecutingAssembly

Questions regards Unity build

Hey, really excited for this project!
Got several questions while testing out with Unity3D.
Wondering how to get "grpc_csharp_ext" native library work on iOS and Android. Since gRPC official c# native plugin only support win/linux/mac platform.

Thank you very much! =)

UnityEditor crash

I am seeing seemingly random editor crash with such call stack:

0x00007FFF5879F7DB (ntdll) RtlpUnWaitCriticalSection
0x00007FFF587A0CE4 (ntdll) RtlEnterCriticalSection
0x00007FFF587A0C10 (ntdll) RtlEnterCriticalSection
0x00007FFF054A9BBD (grpc_csharp_ext) grpcsharp_test_nop
0x00007FFF0549568D (grpc_csharp_ext) grpcsharp_test_nop
0x00007FFF05491B35 (grpc_csharp_ext) grpcsharp_completion_queue_next
0x0000000036C73B3D (Mono JIT Code) (wrapper managed-to-native) Grpc.Core.Internal.NativeMethods/NativeCalls:grpcsharp_completion_queue_next (Grpc.Core.Internal.CompletionQueueSafeHandle)
0x0000000036C74A0D (Mono JIT Code) (wrapper delegate-invoke) Grpc.Core.Internal.NativeMethods/Delegates/grpcsharp_completion_queue_next_delegate:invoke_CompletionQueueEvent__this___CompletionQueueSafeHandle (Grpc.Core.Internal.CompletionQueueSafeHandle)
0x0000000036C72EC5 (Mono JIT Code) [C:\dev\SeedClient\Assets\Catapult\Network\gRPC\Core\Internal\CompletionQueueSafeHandle.cs:78] Grpc.Core.Internal.CompletionQueueSafeHandle:Next () 
0x0000000036C717B9 (Mono JIT Code) [C:\dev\SeedClient\Assets\Catapult\Network\gRPC\Core\Internal\GrpcThreadPool.cs:195] Grpc.Core.Internal.GrpcThreadPool:RunHandlerLoop (Grpc.Core.Internal.CompletionQueueSafeHandle,Grpc.Core.Profiling.IProfiler) 
0x0000000036C715F6 (Mono JIT Code) [C:\dev\SeedClient\Assets\Catapult\Network\gRPC\Core\Internal\GrpcThreadPool.cs:173] Grpc.Core.Internal.GrpcThreadPool/<CreateAndStartThread>c__AnonStorey0:<>m__0 () 
0x0000000001F07392 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
0x00007FFF0B345703 (mono) [c:\buildslave\mono\build\mono\mini\mini.c:4937] mono_jit_runtime_invoke 
0x00007FFF0B298425 (mono) [c:\buildslave\mono\build\mono\metadata\object.c:2623] mono_runtime_invoke 
0x00007FFF0B2C36E7 (mono) [c:\buildslave\mono\build\mono\metadata\threads.c:721] start_wrapper 
0x00007FFF0B3782D5 (mono) [c:\buildslave\mono\build\libgc\win32_threads.c:599] thread_start 
0x00007FFF55F38364 (KERNEL32) BaseThreadInitThunk
0x00007FFF587D70D1 (ntdll) RtlUserThreadStart

It seems to be connected to recreating/disposing channels as I reproduce it when running such test code in a loop:

public IEnumerator TestPingPong()
        {
            for (int i = 0; i < 30; i++)
            {
                Log.Debug("Creating channel");
                Channel channel = UnitTestClient.CreateChannel();
                Log.Debug("Created channel");
                var protocolSerialiser = new SeedProtocolSerializer();
                var marshaller = Marshallers.Create<Message>(protocolSerialiser.ToBytes, protocolSerialiser.ToMessage);
                var method = new Method<Message, Message>(MethodType.DuplexStreaming,
                    "x", "x", marshaller, marshaller);

                var host = "localhost";
                var caller = new EditorWindowSupportsCallInvoker(channel);
                //var caller = new DefaultCallInvoker(channel);
                using (var call = caller.AsyncDuplexStreamingCall(method, host,
                    new CallOptions(deadline: DateTime.UtcNow.AddSeconds(5))))
                {
                    string data = "hello unity";
                    var request = new Ping() {Data = data}.AsMessage();
                    Log.Debug("calling service request:{$request}", request);
                    yield return call.RequestStream.WriteAsync(new Ping() {Data = data}.AsMessage())
                        .ToYieldInstruction();

                    var resultPromise = call.ResponseStream.AsObservable().Take(1).ToYieldInstruction();
                    yield return resultPromise;

                    resultPromise.HasResult.IsTrue();
                    var pong = resultPromise.Result as Message<Pong>;
                    Log.Debug("recieved reply:{reply}", pong);
                    pong.IsNotNull();
                    pong.Body.Data.Is(data + " back");
                    yield return call.RequestStream.CompleteAsync().ToYieldInstruction();
                }

                Log.Debug("Closing channel");
                try
                {
                    yield return channel.ShutdownAsync().ToYieldInstruction();
                }
                finally
                {
                    Log.Debug("Closed channel");
                }
            }

        }

It's definitely something to do with channel.ShutdownAsync() because if you comment it out there is no crash
I was wondering if it's something you have seen before

More Documentation

MagicOnionOption, GroupConfiguration, controller lifecycle, exception handling between server and client,
ImmutableArrayGroup and ConcurrentDIctionaryGroup, How to use MagicOnion.Redis, etc.

Decouple MagicOnion from MessagePack

At the moment many core MagicOnion classes on Unity side are coupled with MessagePack through statics. That makes it hard to use just some parts of framework. For example I am using just core bits with protobuf-net instead of MessagePack and my own server side framework, so every merge with upstream is total pain in places like ChannelContext.cs or MagicOnionClient.cs because of dependencies on MessagePack

I think it's great that MagicOnion comes in fully assembled opinionated package, but it would be even better if it was more layered and decoupled through interfaces allowing people to adapt or rewrite parts of it without hard fork and losing link with original repo

UWP Support

Hello,

Is your project support Universal Windows Platform with Unity3d?

I'm tried to use it in Unity Editor (2017.1.1) and it works fine, and build process from Unity to UWP Application goes fine without error. But when I tried to build UWP Project to get binaries I got several errors. ( Used IL2CPP Scripting Backend)

As a unity project, I used your unity3d sample from the repository.

image

Freeze on Debug in VS

Hi,

We have an issue with constant Unity freezes when you attach VS debugger.
I was wondering if that commit neucc/grpc fixes it?
Would it be possible for you please to update native binaries inside thise repo with the fixed version?

Thank you

Bug on IOS device`s

Hello,

found an issue on iOS device.

Here is a code from the file IFormatterResolver.cs:

public static IMessagePackFormatter<T> GetFormatterWithVerify<T>(this IFormatterResolver resolver)
        {
            IMessagePackFormatter<T> formatter;
            try
            {
                formatter = resolver.GetFormatter<T>();
            }
            catch (TypeInitializationException ex)
            {
                Exception inner = ex;
                while (inner.InnerException != null)
                {
                    inner = inner.InnerException;
                }

                throw inner;
            }

            if (formatter == null)
            {
                throw new FormatterNotRegisteredException(typeof(T).FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name);
            }

            return formatter;
        }
That calls an exception when trying to get an object from server response:

if (formatter == null)
            {
                throw new FormatterNotRegisteredException(typeof(T).FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name);
            }

On other platforms everything works fine though.

Is there a "middleware" in client side?

Say, I want to check every call to the server that if StatusCode.Unauthenticated is returned, I can popup a login window for the user.
How to do it correctly? Thanks!

Improve HTTP/1 Json Gateway

The current HTTP/1 gateway has many overhead, it is only for develpment use, not for production.

I've created fast(est) JSON Serializer.
https://github.com/neuecc/Utf8Json

If MagiOnion becomes serialize to Json directly instead of MessagePack by option,
HTTP/1 gateway becomes faster and can be used gRPC for Web API like grpc-web, grpc-gateway.

Hi, I used moc.exe to generate .cs file is empty, no implementation interface.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MagicOnion;

namespace FooServiceDefinition
{
public interface IMyFirstService : IService
{
UnaryResult SumAsync(int x, int y);
Task<UnaryResult> SumLegacyTaskAsync(int x, int y);
Task<ClientStreamingResult<int, string>> ClientStreamingSampleAsync();
Task<ServerStreamingResult> ServertSreamingSampleAsync(int x, int y, int z);
Task<DuplexStreamingResult<int, string>> DuplexStreamingSampleAync();
}
}

PS E:\Work\CSharpProject\Foo\FooServiceDefinition> .\moc.exe -i .\FooServiceDefinition.csproj -o .\Unity3d\Test.cs
Project Compilation Start:.\FooServiceDefinition.csproj
Project Compilation Complete:00:00:01.0242329

Method Collect Start
Method Collect Complete:00:00:00.0035521
Output Generation Start
[Out].\Unity3d\Test.cs
String Generation Complete:00:00:00.0095782

#pragma warning disable 618
#pragma warning disable 612
#pragma warning disable 414
#pragma warning disable 168
namespace MagicOnion
{
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::MagicOnion;
using global::MagicOnion.Client;

public static partial class MagicOnionInitializer
{
    static bool isRegistered = false;

    [UnityEngine.RuntimeInitializeOnLoadMethod(UnityEngine.RuntimeInitializeLoadType.BeforeSceneLoad)]
    public static void Register()
    {
        if(isRegistered) return;
        isRegistered = true;

    }
}

}
#pragma warning disable 618
#pragma warning disable 612
#pragma warning disable 414
#pragma warning disable 168

namespace MagicOnion.Resolvers
{
using System;
using MessagePack;

public class MagicOnionResolver : global::MessagePack.IFormatterResolver
{
    public static readonly global::MessagePack.IFormatterResolver Instance = new MagicOnionResolver();

    MagicOnionResolver()
    {

    }

    public global::MessagePack.Formatters.IMessagePackFormatter<T> GetFormatter<T>()
    {
        return FormatterCache<T>.formatter;
    }

    static class FormatterCache<T>
    {
        public static readonly global::MessagePack.Formatters.IMessagePackFormatter<T> formatter;

        static FormatterCache()
        {
            var f = MagicOnionResolverGetFormatterHelper.GetFormatter(typeof(T));
            if (f != null)
            {
                formatter = (global::MessagePack.Formatters.IMessagePackFormatter<T>)f;
            }
        }
    }
}

internal static class MagicOnionResolverGetFormatterHelper
{
    static readonly global::System.Collections.Generic.Dictionary<Type, int> lookup;

    static MagicOnionResolverGetFormatterHelper()
    {
        lookup = new global::System.Collections.Generic.Dictionary<Type, int>(0)
        {
        };
    }

    internal static object GetFormatter(Type t)
    {
        int key;
        if (!lookup.TryGetValue(t, out key))
        {
            if (t == typeof(UniRx.Unit))
            {
                return MagicOnion.Resolvers.UniRxIntegrate.UnitFormatter.Instance;
            }
            else if (t == typeof(Nullable<UniRx.Unit>))
            {
                return MagicOnion.Resolvers.UniRxIntegrate.NullableUnitFormatter.Instance;
            }
            return null;
        }

        switch (key)
        {
            default: return null;
        }
    }
}

}

namespace MagicOnion.Resolvers.UniRxIntegrate
{
using System;
using UniRx;
using MessagePack;
using MessagePack.Formatters;

public class UnitFormatter : IMessagePackFormatter<Unit>
{
    public static readonly IMessagePackFormatter<Unit> Instance = new UnitFormatter();

    UnitFormatter()
    {

    }

    public int Serialize(ref byte[] bytes, int offset, Unit value, IFormatterResolver typeResolver)
    {
        return MessagePackBinary.WriteNil(ref bytes, offset);
    }

    public Unit Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
    {
        if (bytes[offset] == MessagePackCode.Nil)
        {
            readSize = 1;
            return Unit.Default;
        }
        else
        {
            throw new InvalidOperationException(string.Format("code is invalid. code:{0} format:{1}", bytes[offset], MessagePackCode.ToFormatName(bytes[offset])));
        }
    }
}

public class NullableUnitFormatter : IMessagePackFormatter<Unit?>
{
    public static readonly IMessagePackFormatter<Unit?> Instance = new NullableUnitFormatter();

    NullableUnitFormatter()
    {

    }

    public int Serialize(ref byte[] bytes, int offset, Unit? value, IFormatterResolver typeResolver)
    {
        return MessagePackBinary.WriteNil(ref bytes, offset);
    }

    public Unit? Deserialize(byte[] bytes, int offset, IFormatterResolver typeResolver, out int readSize)
    {
        if (bytes[offset] == MessagePackCode.Nil)
        {
            readSize = 1;
            return Unit.Default;
        }
        else
        {
            throw new InvalidOperationException(string.Format("code is invalid. code:{0} format:{1}", bytes[offset], MessagePackCode.ToFormatName(bytes[offset])));
        }
    }
}

}

#pragma warning disable 168
#pragma warning restore 414
#pragma warning restore 618
#pragma warning restore 612

Unity generated exception

I tried unity project generate but not working.
error messages to below.

environment

  • Unity 2017.1.0f1(.net 3.5) or Unity 5.6.2f1
  • MagicOnionGenerate from github project

==============================================================
D:\library\Unity\MagicOnion\src\MagicOnion.CodeGenerator\bin\Debug\moc.exe --input=
GRPC-Client.csproj --output=Assets\Scripts\MagicOnion\MagicOnionGenerated.cs
Project Compilation Start:GRPC-Client.csproj
Project Compilation Complete:00:00:04.0922816

Method Collect Start

μ²˜λ¦¬λ˜μ§€ μ•Šμ€ μ˜ˆμ™Έ: System.Exception: Invalid Return Type, method:.cctor returnT
ype:void
μœ„μΉ˜: MagicOnion.CodeAnalysis.MethodCollector.ExtractRequestResponseType(IMet
hodSymbol method, MethodType& methodType, String& requestType, String& responseT
ype, ITypeSymbol& unwrappedOriginalResponseType) 파일 D:\library\Unity\MagicOnio
n\src\MagicOnion.CodeGenerator\CodeAnalysis\MethodCollector.cs:쀄 187
μœ„μΉ˜: MagicOnion.CodeAnalysis.MethodCollector.CreateMethodDefinition(IMethodS
ymbol y) 파일 D:\library\Unity\MagicOnion\src\MagicOnion.CodeGenerator\CodeAnaly
sis\MethodCollector.cs:쀄 123
μœ„μΉ˜: System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() μœ„μΉ˜: System.Linq.Buffer1..ctor(IEnumerable1 source) μœ„μΉ˜: System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source)
μœ„μΉ˜: MagicOnion.CodeAnalysis.MethodCollector.b__8_0(INamedTypeSymbol
x) 파일 D:\library\Unity\MagicOnion\src\MagicOnion.CodeGenerator\CodeAnalysis\Me
thodCollector.cs:쀄 73
μœ„μΉ˜: System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext() μœ„μΉ˜: System.Linq.Enumerable.<ConcatIterator>d__581.MoveNext()
μœ„μΉ˜: System.Linq.Buffer1..ctor(IEnumerable1 source)
μœ„μΉ˜: System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
μœ„μΉ˜: MagicOnion.CodeAnalysis.MethodCollector.Visit() 파일 D:\library\Unity\M
agicOnion\src\MagicOnion.CodeGenerator\CodeAnalysis\MethodCollector.cs:쀄 72
μœ„μΉ˜: MagicOnion.CodeGenerator.Program.Main(String[] args) 파일 D:\library\Un
ity\MagicOnion\src\MagicOnion.CodeGenerator\Program.cs:쀄 93

Core Implement

  • Unary
    • zero argument
    • single argument
    • multiple argument
  • ClientStreaming
  • ServerStreaming
    • zero argument
    • single argument
    • multiple argument
  • DuplexStreaming
  • Client configurations(With...)
  • Filter Impelements
  • Logging
  • Mock
  • Edge case tests/Varidation tests
    • Nil
    • Nested Class
    • Exception handling
    • header write/read

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.