egmkang 服务端开发工程师

orleans发送广播消息

2016-08-30
C#

一个client发送消息给orleans, 就只需要掉用Grain的函数就行了. 但是有时候Grain需要发送消息给client, 在orleans里面, 就只能通过Observer来实现.

public interface IChat : IGrainObserver
{
  void ReceiveMessage(string message);
}

public class Chat : IChat
{
  public void ReceiveMessage(string message)
  {
    Console.WriteLine(message);
  }
}

class HelloGrain : Grain, IHello
{
  private ObserverSubscriptionManager<IChat> _subsManager;
  public override async Task OnActivateAsync()
  {
    _subsManager = new ObserverSubscriptionManager<IChat>();
    await base.OnActivateAsync();
  }
  public async Task Subscribe(IChat observer)
  {
    _subsManager.Subscribe(observer);
  }
  public async Task UnSubscribe(IChat observer)
  {
    _SubsManager.Unsubscribe(observer);
  }
}

public Task SendUpdateMessage(string message)
{
  _SubsManager.Notify(s => s.ReceiveMessage(message));
  return TaskDone.Done;
}

//下面就是Grain发送消息给Client的代码
var friend = GrainClient.GrainFactory.GetGrain<IHello>(0);
Chat c = new Chat();

var obj = await GrainClient.GrainFactory.CreateObjectReference<IChat>(c);
await friend.Subscribe(obj);

有了上面的代码, 我们就可以按照自己的需求造一个广播出来.

  • 发送消息给Client上所有的人
  • 发送消息给Client上某一部分人
  • 发送消息给Client上某一个人
enum DestType
{
  DestType_All    = 1,
  DestType_Server = 2,
  DestType_Player = 3,
}

//这是我们的观察者
public interface IGatewayObserver : IGrainObserver
{
  void SendMessage(int destType, long dest, int msgid, byte[] buffer);
}

public interface IAllGatewayGrain : IGrainWithIntegerKey
{
  //注册网关
  Task RegisterGateway(string key);
  Task UnRegisterGateway(string key);

  //发送消息
  Task SendMessage(int destType, long dest, int msgid, byte[] buffer);

  //注册观察者
  Task RegisterObserver(string gateway, IGatewayObserver);
}

public interface IGatewayGrain : IGrainWithStringKey
{
  Task SendMessage(int destType, long dest, int msgid, byte[] buffer);

  Task RegisterObserver(string gateway, IGatewayObserver);
}

上面是接口的设计, 然后只需要在Client启动的时候, 把自己注册到两个Grain里面去, 然后其他的Grain就可以通过两个Grain来发送针对所有人, 服务器, 和个人的消息了.


Similar Posts

Comments