Как передать значение в Hub через консоль или через контроллер. SignalR
Мне нужно, чтобы я мог отправить сообщение через консоль. Я пробовал отправлять POST запрос со значениями user и message, а затем вызывать метод Hub напрямую, но это результата не дало. Ошибка с null. Вот код, который я использовал
Так отправляю POST запрос:
client.BaseAddress = new Uri("https://localhost:44395");
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("user", "10"),
new KeyValuePair<string, string>("message", "3")
});
var result1 = await client.PostAsync("/Home/Area", content);
string resultContent1 = await result1.Content.ReadAsStringAsync();
Console.WriteLine(resultContent1);
Он работает, все хорошо.
Сам Controller:
public async Task<string> Area(string user, string message)
{
ChatHub ch = new ChatHub();
return $"{ch.SendMessage(user, message)}";
}
Hub:
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Наверняка можно сразу на Hub отправить как-то, но я вообще не нашел об этом никакой информации...
Что мне нужно: Отправить через консоль сообщение на Hub, которое разошлется всем клиентам.
Ответы (1 шт):
Разобрался. Пришлось покопаться в англоязычных статьях и наконец нашел то, что мне нужно!
Hub:
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Controller:
[ApiController]
[Route("api/broadcast")]
public class BroadcastController : ControllerBase
{
private readonly IHubContext<ChatHub> _hub;
public BroadcastController(IHubContext<ChatHub> hub)
{
_hub = hub;
}
[HttpGet]
public async Task Get(string user, string message)
{
await _hub.Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
...
}
...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chathub");
...
});
}
index.cshtml:
@page
<div class="container">
<div class="row"> </div>
<div class="row">
<div class="col-2">User</div>
<div class="col-4"><input type="text" id="userInput" /></div>
</div>
<div class="row">
<div class="col-2">Message</div>
<div class="col-4"><input type="text" id="messageInput" /></div>
</div>
<div class="row"> </div>
<div class="row">
<div class="col-6">
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>
chat.js:
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
//Disable send button until connection is established
document.getElementById("sendButton").disabled = true;
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + " says " + msg;
var li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
});
connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
Теперь перейдем, собственно, к консоли.
Устанавливаем соединение к Hub через консоль вот так:
static async Task Main(string[] args)
{
HubConnection connection = new HubConnectionBuilder()
.WithUrl("http://localhost:18128/ChatHub")
.WithAutomaticReconnect()
.Build();
await connection.StartAsync();
string message = Console.ReadLine();
await connection.InvokeAsync("SendMessage", "Console", message);
}
}
Примечание:
Может быть ошибка связанная с тем, что у класса HubConnectionBuilder нету метода WithUrl. Это связано с тем, что Visual Studio установил вам лишние библиотеки и связал класс HubConnectionBuilder с Microsoft.AspNetCore.SignalR.Client.Core (если вы устанавливали через "показать возможные решения", то Visual Studio установит вам обе библиотеки Client.Core и Client) Рекомендую установить вручную Microsoft.AspNetCore.SignalR.Client и подключить вот так using Microsoft.AspNetCore.SignalR.Client;.