過去 3 か月間、SignalR が JIT (ジャストインタイム) レベルでどのように機能するかについては、まだ手がかりがありません。クライアントにジャストインタイムでデータを送信するハブを構築しようとしています。クライアントはデータを受信し、それに従って動作します。
編集: JIT 送受信の意味がわからない場合は、
これは、新しいデータが利用可能になったときに、サーバーが接続されたソケット クライアント データを送信できることを意味していました。ソケット接続は、サーバーがシャットダウンされている/問題がある場合、またはクライアントがソケットから切断された場合にのみ閉じられます。つまり、何があっても、サーバーから新しいデータが発生すると、常にそのデータを 1 つずつ接続クライアントに送信します。
だからここに私が見逃している/混乱しているものがあります:
- SubscribeToAll (以下の TickerHub.cs をチェックしてください) メソッドは、クライアントに通知してビープ音を鳴らす新しいデータがあるときに呼び出す場所ですか、それともどこですか?
- 非同期の WriteToChannel がどのように機能するかを知っています。基本的に、コレクションをアイテムごとにクライアントに送信します。重要な問題は、この関数全体を JIT に変換するにはどうすればよいかということです。また、このハブにサブスクライブしているクライアントのリストはどこで処理すればよいでしょうか?
現在、TickerHub.cs はデータセット (CurrencyPairs という名前) を取得し続け、クライアントに無期限にブロードキャストします。CurrencyPairs を 24 時間年中無休で同期および更新するバックグラウンド サービスがあります。バックグラウンド サービスからハブを呼び出して、ハブがその新しいデータを接続されたクライアントにブロードキャストできるようにする方法を説明/表示するには、SignalR の専門家の助けが必要です。
TickerHub.cs
public class TickerHub : Hub, ITickerHubClient
{
private IEnumerable<CurrencyPair> _currencyPairs;
private readonly ICurrencyPairService _cpService;
public TickerHub(ICurrencyPairService cpService)
{
_cpService = cpService;
}
public async Task<NozomiResult<CurrencyPair>> Tickers(IEnumerable<CurrencyPair> currencyPairs = null)
{
var nozRes = new NozomiResult<CurrencyPair>()
{
Success = true,
ResultType = NozomiResultType.Success,
Data = currencyPairs
};
return nozRes;
}
// We can use this to return a payload
public async Task<ChannelReader<NozomiResult<CurrencyPair>>> SubscribeToAll()
{
// Initialize an unbounded channel
//
// Unbounded Channels have no boundaries, allowing the server/client to transmit
// limitless amounts of payload. Bounded channels have limits and will tend to
// drop the clients after awhile.
var channel = Channel.CreateUnbounded<NozomiResult<CurrencyPair>>();
_ = WriteToChannel(channel.Writer); // Write all Currency Pairs to the channel
// Return the reader
return channel.Reader;
// This is a nested method, allowing us to write repeated methods
// with the same semantic conventions while maintaining conformity.
async Task WriteToChannel(ChannelWriter<NozomiResult<CurrencyPair>> writer)
{
// Pull in the latest data
_currencyPairs = _cpService.GetAllActive();
// Iterate them currency pairs
foreach (var cPair in _currencyPairs)
{
// Write one by one, and the client receives them one by one as well
await writer.WriteAsync(new NozomiResult<CurrencyPair>()
{
Success = (cPair != null),
ResultType = (cPair != null) ? NozomiResultType.Success : NozomiResultType.Failed,
Data = new[] {cPair}
});
}
// Beep the client, telling them you're done
writer.Complete();
}
}
}
私のクライアント側のコードがうまくいかないかどうかを知りたい場合は、ここにあります
using Microsoft.AspNetCore.SignalR.Client;
using Newtonsoft.Json;
using Nozomi.Client.Data.Interfaces;
using Nozomi.Data;
using Nozomi.Data.CurrencyModels;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Nozomi.Client
{
public class NozomiClient
{
private CancellationToken _tickerStreamCancellationToken;
private string ServerPath;
private HubConnection _hubConnection;
public NozomiClient(string serverPath)
{
ServerPath = serverPath;
_hubConnection = new HubConnectionBuilder()
.WithUrl(serverPath)
.Build();
}
public async Task InitializeAsync()
{
await _hubConnection.StartAsync();
}
public async Task StreamTickers()
{
// Setup the channel for streaming
var streamTickerChannel = await _hubConnection.StreamAsChannelAsync<NozomiResult<CurrencyPair>>("SubscribeToAll", CancellationToken.None);
// Setup the asynchronous data stream
// https://docs.microsoft.com/en-us/aspnet/core/signalr/streaming?view=aspnetcore-2.1#net-client
//while (await streamTickerChannel.WaitToReadAsync())
//{
// while (streamTickerChannel.TryRead(out var cp))
// {
// Console.WriteLine(JsonConvert.SerializeObject(cp));
// }
//}
_hubConnection.On<CurrencyPair>("SubscribeToAll", cp =>
{
Console.WriteLine(cp);
});
while (!_tickerStreamCancellationToken.IsCancellationRequested)
{
if (await streamTickerChannel.WaitToReadAsync())
{
while (streamTickerChannel.TryRead(out var cp))
{
Console.WriteLine(JsonConvert.SerializeObject(cp));
}
}
Console.WriteLine("Processing");
Thread.Sleep(1000);
}
}
public ICurrencyPair CurrencyPairs { get; }
public ISource Sources { get; }
}
}