Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]MagicOnion 2.0.0(-alpha), StreamingHub #58

Merged
merged 22 commits into from Dec 14, 2018
Merged

[WIP]MagicOnion 2.0.0(-alpha), StreamingHub #58

merged 22 commits into from Dec 14, 2018

Conversation

neuecc
Copy link
Member

@neuecc neuecc commented Nov 25, 2018

Currently available in NuGet, you can try it.
https://www.nuget.org/packages/MagicOnion/2.0.1-alpha

new feature StreamingHub is like SignalR or Socket.IO.
It can be handle bi-directional streaming easily.

// common(server/client) interfaces

public interface IMessageReceiver
{
    Task OnReceiveMessage(string senderUser, string message);
}

public interface IChatHub : IStreamingHub<IChatHub, IMessageReceiver>
{
    Task<Nil> JoinAsync(string userName, string roomName);
    Task<Nil> LeaveAsync();
    Task SendMessageAsync(string message);
}

// server impl

public class ChatHub : StreamingHubBase<IChatHub, IMessageReceiver>, IChatHub
{
    // insantiate per user connected and live while connecting.
    string userName;
    IGroup room;

    // return Task<T> wait server completed.
    public Task<Nil> JoinAsync(string userName, string roomName)
    {
        this.userName = userName;
        this.room = Group.Add("InMemoryRoom:" + roomName, this.Context);

        return NilTask;
    }

    // return Task is fire and forget(does not wait server completed).
    public async Task SendMessageAsync(string message)
    {
        // broadcast to connected group(same roomname members).
        await Broadcast(room).OnReceiveMessage(this.userName, message);
    }

    public async Task<Nil> LeaveAsync()
    {
        await BroadcastExceptSelf(room).OnReceiveMessage(userName, "SYSTEM_MESSAGE_LEAVE_USER");
        room.Remove(this.Context);

        return Nil.Default;
    }

    protected override ValueTask OnConnecting()
    {
        return CompletedTask; // you can hook connecting event.
    }

    protected override ValueTask OnDisconnected()
    {
        room?.Remove(this.Context); // remove from group.
        return CompletedTask;
    }
}

// client

public class ClientProgram : IMessageReceiver
{
    public async Task Start(string user, string room)
    {
        var channel = new Channel("localhost:12345", ChannelCredentials.Insecure);

        var client = StreamingHubClient.Connect<IChatHub, IMessageReceiver>(channel, this);
        // RegisterDisconnect(client);
        try
        {

            await client.JoinAsync(user, room);

            await client.SendMessageAsync("Who");
            await client.SendMessageAsync("Bar");
            await client.SendMessageAsync("Baz");

            await client.LeaveAsync();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        finally
        {
            await client.DisposeAsync();
        }
    }

    async void RegisterDisconnect(IChatHub client)
    {
        try
        {
            // you can wait disconnected event
            await client.WaitForDisconnect();
        }
        finally
        {
            // try-to-reconnect? logging event? etc...
            Console.WriteLine("disconnected");
        }
    }

#pragma warning disable CS1998

    public async Task OnReceiveMessage(string senderUser, string message)
    {
        Console.WriteLine(senderUser + ":" + message);
    }
}

// ---- run test.

var foo = new ClientProgram().Start("Foo", "TEST_ROOM");
var bar = new ClientProgram().Start("Bar", "TEST_ROOM");

await Task.WhenAll(foo, bar);

@neuecc
Copy link
Member Author

neuecc commented Nov 27, 2018

Unity supports(does not includes code generator so work only on unity editor).

Download latest gRPC/Unity build from gRPC build server and import it.
for example grpc_unity_package.1.18.0-dev.zip from this link.
https://packages.grpc.io/archive/2018/11/e0d9692fa30cf3a7a8410a722693d5d3d68fb0fd-1e59a50b-4ebf-4564-849e-ce82ca67fb17/index.xml

Import MagicOnion.Unity.2.0.1-alpha.zip package.

modifying player settings configuration like this.

image

  • .NET 4.x Equivalent
  • IL2CPP/Mono
  • .NET 4.x
  • ENABLE_UNSAFE_MSGPACK
  • Allow unsafe Code

You can create MagicOnion client from StreamingHubClient.Connect or MagicOnionClient.Create.

@neuecc
Copy link
Member Author

neuecc commented Dec 4, 2018

In NuGet, 2.0.2-alpha has been released.

All Hub methods wait server execution completed in default.
If you want to use FireAndForget, you can use client.FireAndForget().FooMethod().

All Hub methods receive exception when server throws exception.

Receiver interface's return type can choose both void and Task.

Add UniversalCodeGenerator(moc.exe), it supports linux-x64, win-x64, osx-x64.
moc supports StreamingHub code generate.

You can download moc and .unitypackage here.
https://github.com/neuecc/MagicOnion/releases/tag/2.0.2

@neuecc neuecc merged commit 43757dd into master Dec 14, 2018
@neuecc neuecc deleted the v2 branch December 14, 2018 10:56
AntonC9018 pushed a commit to AntonC9018/MagicOnion that referenced this pull request Sep 13, 2022
MagicOnion2, StreamingHub
AntonC9018 pushed a commit to AntonC9018/MagicOnion that referenced this pull request Sep 13, 2022
MagicOnion2, StreamingHub
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant