SignalR和类型化对象

本文关键字:对象 类型化 SignalR | 更新日期: 2023-09-27 18:22:03

我有一个非常基本的自托管Web服务,使用SignalR2.x,配置如下:

服务器:

internal class WebService
{
    public void Configuration( IAppBuilder app )
    {
        var config = new HttpConfiguration { DependencyResolver = new ControllerResolver() };
        config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
        config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
        config.Routes.MapHttpRoute( "Default", "{controller}/{id}", new { id = RouteParameter.Optional } );
        app.UseWebApi( config );
        app.MapConnection<EventDispatcher>( "", new ConnectionConfiguration { EnableCrossDomain = true } );
        GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => JsonSerializer.Create(new JsonSerializerSettings
                                            {
                                                TypeNameHandling = TypeNameHandling.All
                                            }));
        app.MapHubs();
    }
}

发送消息的服务器代码:

public class Notifier
{
    static readonly IPersistentConnectionContext Context = GlobalHost.ConnectionManager.GetConnectionContext<EventDispatcher>();
    public static void NotifyAll( NotificationType type, object obj )
    {
        Context.Connection.Broadcast( ConstructEvent( type, obj ) );
    }
    public static object ConstructEvent( NotificationType type, object obj )
    {
        var notevent =  new { Event = type.ToString(), Data = obj };
        return notevent;
    }
}

客户端:

void connect()
{
    var _eventHandler = new Connection(Address);
    _eventHandler.JsonSerializer.TypeNameHandling = TypeNameHandling.Objects;
    _eventHandler.Received += eventHandler_Received;
    _eventHandler.Start().Wait();
}

web服务很好地返回了类型化的JSON,但SignalR发送的更新是纯JSON。我是不是遗漏了什么?

SignalR和类型化对象

尽管整个设置相当深奥,但以下是感兴趣的人的解决方案。

我认为问题是由使GlobalHost.ConnectionManager.GetConnectionContext静态引起的。通过这样做,我认为我在正确设置WebService DependencyResolver之前创建了一个PersistentConnection(尽管我不确定为什么会这样)。通过再次获取每个事件的ConnectionContext来解决问题:

public class Notifier
{
    public static void NotifyAll(NotificationType type, object obj)
    {
        var context = GlobalHost.ConnectionManager.GetConnectionContext<EventDispatcher>();
        var output = ConstructEvent(type, obj);
        context.Connection.Broadcast(output);
    }
    protected static object ConstructEvent(NotificationType type, object obj)
    {
        var notevent = new { Event = type.ToString(), Data = obj };
        return notevent;
    }
}

而不是:

public class Notifier
{
    static readonly IPersistentConnectionContext Context = GlobalHost.ConnectionManager.GetConnectionContext<EventDispatcher>();
    public static void NotifyAll(NotificationType type, object obj)
    {
        var output = ConstructEvent(type, obj);
        Context.Connection.Broadcast(output);
    }
    protected static object ConstructEvent(NotificationType type, object obj)
    {
        var notevent = new { Event = type.ToString(), Data = obj };
        return notevent;
    }
}