Signalr 信号器:在客户端和集线器之间使用基类型消息

Signalr 信号器:在客户端和集线器之间使用基类型消息,signalr,Signalr,我对信号员来说是个新手,所以我会尽可能清楚地说出来。以下是我要实现的目标: 1.Create self-hosted web application using SignalR 2.Create WPF rich client which will communicate with above-mentioned server app. 3.Use strongly typed request/response messages which inherit from base types res

我对信号员来说是个新手,所以我会尽可能清楚地说出来。以下是我要实现的目标:

1.Create self-hosted web application using SignalR
2.Create WPF rich client which will communicate with above-mentioned server app.
3.Use strongly typed request/response messages which inherit from base types respectively to pass data from client to server and vice-versa.
以下是我的请求/响应消息的一些定义:

//Base request message
public class HubRequestMessageBase
{

}

//Base response message
public class HubResponseMessageBase
{
    public bool Success { get; set; }
    public Exception Error { get; set; }
}

//Request message to query node by name
public class QueryNodeRequest : HubRequestMessageBase
{
    public string Name { get; set; }
    public Guid Identifier { get; set; }
}

//Response message carrying metadata for the specified node
public class QueryNodeResponse : HubResponseMessageBase
{
   public NodeMetadata NodeMetadata { get; set; }
}
现在,如果我在服务器方法上定义如下:

//Main method for handling client requests
public void HandleClientRequest(HubRequestMessageBase message)
{
    //Omitted for brevity
}
并从客户端调用服务器方法,如下所示:

internal async void QueryNode(string name)
{
    QueryNodeRequest req = new QueryNodeRequest();
    req.Name = name;

    await HubProxy.Invoke("HandleClientRequest", new object[] { req });
}
在服务器端,我仍然在HandleClientRequest方法中获取HubRequestMessageBase作为message类型的参数,而不是QueryNodeRequest。现在,经过一些挖掘,我了解到Signal默认情况下不会处理多态性(或者消息没有被正确序列化/反序列化,这是我所期望的类型-在本例中是继承自HubRequestMessageBaseQueryNodeRequest

我的问题是:是否有可能在客户端和服务器上使用JsonSerializer设置来实现这一点?请注意,我已经尝试了以下代码(以及一些变体),但没有成功(在服务器上):

提前谢谢

干杯,
Civa必须实现并注册它。默认值只是将
JValues
转换为目标参数类型。

我已经解决了这个问题

问题的根本原因是信号机代码库中的这一行 其中,Signaler使用默认序列化程序,不允许您注入自己的序列化程序

我的解决方案是通过设置参数JObject的类型来绕过该序列化程序 然后通过使用序列化程序的自定义实例和基于JObject的JTokenReader,将该JObject turing到hub中的我的具体类型中

My Hub方法(注意ClientCommand是所有可能命令的抽象基类)

信封类型

public sealed class Envelope
{
    public JObject Command { get; set; }
}

通过使用TypeNameHandling=TypeNameHandling.JsonSerializer上的对象,我所需要做的就是在我从客户端发送的对象中包含$type属性。

Hello Pawel,非常感谢您的回答,我将尝试此方法并尽快通知您。不幸的是,此方法没有解决我的问题,因为IJsonValue already包含我期望的数据类型:
{“$type”:“Zenith.Network.Api.Messages.QueryNodeRequest,Zenith.Network.Api”,…}
,我无法将其转换回HubRequestMessageBase(作为参数类型中的值)。最后,我为每个请求类型编写了单独的方法,并按预期工作。但是,我会将您的响应标记为已接受,因为这是处理多态消息类型的一种方法,也许有人会发现它很有用。我知道这是一个老问题,但非常感谢您的回答。StocksR,很好,它确实很有用。干杯!
public async Task DispatchCommand(Envelope envelope)
{
    var settings = new JsonSerializerSettings
                   {
                       TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
                       TypeNameHandling = TypeNameHandling.Objects
                   };
    var serializer = JsonSerializer.Create(settings);
    var c = (ClientCommand) serializer.Deserialize(new JTokenReader(envelope.Command), typeof(ClientCommand));

    await commandDispatcher.SendCommand(c);
}
public sealed class Envelope
{
    public JObject Command { get; set; }
}