Using Generic Type as Message in Server Sent Events (SSE)

Hello,

I need to send messages to my Server Events client that use generic type DTO.

For example:

 MyMessage<MyTypeA>
 MyMessage<MyTypeB>

I’m sending those to the client using this

ServerEvents.NotifyUserName(name, selector, message, channel)

where selector looks like this: “cmd.MyMessage`1[[MyTypeA]]” and it is constructed from adding “cmd.” to message full type name (with generic type) so that it can be used with named receiver class on the client.

On the client I have a named receiver class that looks like this:

class MyReceiver : ServerEventReceiver
{
  public Task ProcessA(MyMessage<MyTypeA> message)
  { . . . }
  public Task ProcessB(MyMessage<MyTypeB> message)
  { . . . }
}

However these methods never get executed.

I looked into this code in the framework:

internal class ReceiverExec<T>
{
  public static void Reset()
  {
    . . .
    var methods = typeof(T).GetMethodInfos().Where(x => x.IsPublic && !x.IsStatic);
    foreach (var mi in methods)
    {
      . . .
      var actionName = mi.Name;
      . . .
      var requestType = args[0].ParameterType;
      var execCtx = new ReceiverExecContext
      {
        Id = ReceiverExecContext.Key(actionName, requestType.GetOperationName()),
          ServiceType = typeof(T),
          RequestType = requestType,
          Method = mi.Name
      };
    }
  }
}

The UrlExtensions.GetOperationName(this Type type) has code that removes generic type name from operation name.

Is there anything we can do to support generic type messages / requests? Perhaps the ReceiverExecContext.Key generation can use a delegate?

What do you think?

It’s a requirement that all Request DTOs need to be a concrete non-generic class where the DTO Type name is what identifies what Service is called and the DTO is what defines the Service contract which we also discourage from using inheritance to hide its Type definition.

I understand and I agree.

All initial messages in my REST service implementation are concrete DTOs. It is only when they forwarded to the SSE clients, they get wrapped into a generic parent “message” DTO.

Anyway, I ended up taking standard approach with using method names as selectors for processing these wrapped DTOs as described in Named Receivers.

There is also “void NoSuchMethod(string selector, object message)” that can be overridden to handle anything.

Thanks for your time!

1 Like