通过 Websocket 反序列化收到的 Json-Rpc 数据 API
Deserializing received Json-Rpc data via Websocket API
我正在尝试找出一种创建通用 Websocket JsonRpc 客户端的方法。
连接后我开始一个循环来侦听来自 WebSocket API 的数据并将该数据作为字符串发送到事件。我想 return 通用 JsonRpcResponse<T>
对象,但不确定如何或是否可能。
其中 JsonRpcResponse
具有规范中定义的 Id
和 Method
字段,T
是特定类型,具体取决于接收到的数据。
据我所知,这里无法使用泛型,因为我必须调用另一个具有非泛型类型的事件或 object
来传递该数据。
public event Func<string, Task>? OnDataReceived;
public async Task ConnectAsync()
{
Uri uri = new Uri(_url);
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(3000);
await _client.ConnectAsync(uri, cancellationTokenSource.Token);
// Start listening for data
await Task.Factory.StartNew(async () =>
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
while (_client.State == WebSocketState.Open && !cancellationTokenSource.IsCancellationRequested)
{
var receivedData = await ReadStringAsync(cancellationTokenSource.Token);
if (OnDataReceived != null)
{
await OnDataReceived.Invoke(receivedData);
}
}
};
}
这个怎么样:
namespace GenericJsonResponse {
/// <summary>
/// Desired returned type
/// </summary>
/// <typeparam name="T"></typeparam>
public class JsonResponse<T> {
public T? Data { get; set; }
public int Id { get; set; } = 0;
public string Method { get; set; } = string.Empty;
/// <summary>
/// Convert string to anew instance
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
/// <remarks>will have to add to each sub class</remarks>
public static T FromJson(string json) {
throw new NotImplementedException();
}
}
/// <summary>
/// Generic socket listener / sub class per type
/// </summary>
/// <typeparam name="T"></typeparam>
public class GenericSocketListener<T> {
/// <summary>
/// exposes event with generic response
/// </summary>
public event Func<string, Task<JsonResponse<T>>>? OnDataReceived;
/// <summary>
/// Listen to socket
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public virtual async Task Listen( CancellationToken token) {
string data = string.Empty;
while (! token.IsCancellationRequested) {
// listen... and get typed result, save string to data
JsonResponse<T> result = await OnDataReceived.Invoke(data);
}
}
}
/// <summary>
/// Dummy poco
/// </summary>
public class Person {
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
}
/// <summary>
/// Class that will listen to people
/// </summary>
public class PersonSocketListener : GenericSocketListener<Person> {
}
}
我正在尝试找出一种创建通用 Websocket JsonRpc 客户端的方法。
连接后我开始一个循环来侦听来自 WebSocket API 的数据并将该数据作为字符串发送到事件。我想 return 通用 JsonRpcResponse<T>
对象,但不确定如何或是否可能。
其中 JsonRpcResponse
具有规范中定义的 Id
和 Method
字段,T
是特定类型,具体取决于接收到的数据。
据我所知,这里无法使用泛型,因为我必须调用另一个具有非泛型类型的事件或 object
来传递该数据。
public event Func<string, Task>? OnDataReceived;
public async Task ConnectAsync()
{
Uri uri = new Uri(_url);
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(3000);
await _client.ConnectAsync(uri, cancellationTokenSource.Token);
// Start listening for data
await Task.Factory.StartNew(async () =>
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
while (_client.State == WebSocketState.Open && !cancellationTokenSource.IsCancellationRequested)
{
var receivedData = await ReadStringAsync(cancellationTokenSource.Token);
if (OnDataReceived != null)
{
await OnDataReceived.Invoke(receivedData);
}
}
};
}
这个怎么样:
namespace GenericJsonResponse {
/// <summary>
/// Desired returned type
/// </summary>
/// <typeparam name="T"></typeparam>
public class JsonResponse<T> {
public T? Data { get; set; }
public int Id { get; set; } = 0;
public string Method { get; set; } = string.Empty;
/// <summary>
/// Convert string to anew instance
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
/// <remarks>will have to add to each sub class</remarks>
public static T FromJson(string json) {
throw new NotImplementedException();
}
}
/// <summary>
/// Generic socket listener / sub class per type
/// </summary>
/// <typeparam name="T"></typeparam>
public class GenericSocketListener<T> {
/// <summary>
/// exposes event with generic response
/// </summary>
public event Func<string, Task<JsonResponse<T>>>? OnDataReceived;
/// <summary>
/// Listen to socket
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public virtual async Task Listen( CancellationToken token) {
string data = string.Empty;
while (! token.IsCancellationRequested) {
// listen... and get typed result, save string to data
JsonResponse<T> result = await OnDataReceived.Invoke(data);
}
}
}
/// <summary>
/// Dummy poco
/// </summary>
public class Person {
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
}
/// <summary>
/// Class that will listen to people
/// </summary>
public class PersonSocketListener : GenericSocketListener<Person> {
}
}