私はSignalRの初心者です。 Asp.Net Core WebAPIをセットアップして、他のクライアントがSignalRを使用してそれに接続し、リアルタイムデータを取得できるようにしようとしています。私のハブクラスは次のとおりです。
_public class TimeHub : Hub
{
public async Task UpdateTime(string message)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
_
私は次のようなリレークラスを持っています:
_public class TimeRelay : ITimeRelay
{
private readonly IHubContext<TimeHub> _timeHubContext;
public TimeRelay(IHubContext<TimeHub> context)
{
_timeHubContext = context;
Task.Factory.StartNew(async () =>
{
while (true)
{
await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
Thread.Sleep(2000);
}
});
}
}
_
スタートアップクラス:
_public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseSignalR((x) =>
{
x.MapHub<TimeHub>("/timeHub");
});
app.UseMvc();
}
_
クライアントはコンソールアプリケーションであり、コードは次のとおりです。
_class Program
{
static Action<string> OnReceivedAction = OnReceived;
static void Main(string[] args)
{
Connect();
Console.ReadLine();
}
private static async void Connect()
{
var hubConnectionBuilder = new HubConnectionBuilder();
var hubConnection = hubConnectionBuilder.WithUrl("http://localhost:60211/timeHub").Build();
await hubConnection.StartAsync();
var on = hubConnection.On("ReceiveMessage", OnReceivedAction);
Console.ReadLine();
on.Dispose();
await hubConnection.StopAsync();
}
static void OnReceived(string message)
{
System.Console.WriteLine($"{message}");
}
}
_
アプリケーションをデバッグしてみました。クライアントはTimeHub
に正常に接続されました。クライアントが接続されると、_Clients.All
_の接続数が0から1に変更されました。ただし、await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
が実行されると、UpdateTime
のTimeHub
関数は実行されず、クライアントはメッセージを受け取りません。
TimeRelay
クラスの_"UpdateTime"
_のメソッドとして、_"SendMessage"
_、_"ReceiveMessage"
_、および_Clients.All.SendAsync
_を使用してみました。何も機能しませんでした。誰かがこれで私の間違いを指摘できますか?.
私はそれを機能させ、ここで答えようと思いました。ヒントをありがとう@TaoZhou。
私の間違いは、サーバーから「UpdateTime」を送信し、クライアントで「ReceiveMessage」を待機することでした。
理想的には、コードは次のようになります。
SignalRサーバー:await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
SignalRクライアント:var on = hubConnection.On("UpdateTime", OnReceivedAction);
この場合、サーバーから送信されたメッセージはすべてクライアントで即座に受信されます。
詳細については、質問に記載されているコードを参照してください。
Clients
の場合、サーバーに接続しているクライアントがない場合はnullになります。開始するためにAsp.Net Core SignalR
およびConsole App
同時に、コンソールアプリがsignalRサーバーに接続する前にClients
が呼び出される可能性があるため、Index
がnullになる可能性があります。
以下の手順を試してください。
TimeHub
を変更します
public class TimeHub: Hub
{
public async Task UpdateTime(string message)
{
if (Clients != null)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
}
登録TimeHub
services.AddSingleton<TimeHub>();
コントローラ
public class HomeController : Controller
{
private readonly TimeHub _timeHub;
public HomeController(TimeHub timeHub)
{
_timeHub = timeHub;
}
public IActionResult Index()
{
Task.Factory.StartNew(async () =>
{
while (true)
{
try
{
await _timeHub.UpdateTime(DateTime.Now.ToShortDateString());
Thread.Sleep(2000);
}
catch (Exception ex)
{
}
}
});
return View();
}