#c# #javascript #asp.net-mvc #signalr #signalr-hub
#c# #javascript #asp.net-mvc #signalr #signalr-hub
Вопрос:
Я настроил SignalR hub для связи между сервером и клиентом. Код на стороне сервера-концентратора хранится в классе с именем Hooking.cs. Я хочу иметь возможность вызывать метод, определенный в Hooking.cs, чтобы я мог передавать сообщения любым подключенным клиентам из любого места в моем приложении. Похоже, что новый экземпляр Hooking.cs создается для каждого вызова клиент / сервер, поэтому я надеялся, что смогу использовать что-то вроде
var hooking = new Hooking();
hooking.Test();
с помощью метода Test(), определенного в Hooking.cs, такого как
public static void Test() {
Clients.test()
}
и с помощью javascript на стороне клиента
var hooking = $.connection.hooking;
hooking.test = function() { alert("test worked"); };
$.connection.hub.start()
К сожалению, это не так просто, поскольку клиенты не являются статическими, поэтому недоступны из статического метода.
Просматривая исходный код SignalR, я наткнулся на метод, который выглядел многообещающим, Hubs.Invoke(string hubName, string method, params object[] args)
, поэтому я надеюсь, что смогу использовать что-то вроде, Hubs.Invoke("Hooking", "Test")
но я не могу заставить его работать.
Любая помощь в этом была бы очень признательна
Комментарии:
1. Но, может быть, вы сможете мне помочь 😉 Есть идеи, как выполнить ваш код js в вашем широковещательном сообщении для всех других клиентов, а не для вызывающего абонента, который отправил сообщение? 🙂
2. К сожалению, я этого не делаю. Я обрабатывал эту клиентскую часть, отправляя идентификатор клиента обратно с ответом и просто не вызывая функцию, если идентификатор совпадает
Ответ №1:
Это правильный способ для SignalR 2.x:
var context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
context.Clients.All.addMessage(message);
В принципе, вы можете использовать распознаватель зависимостей для текущего хоста для разрешения IConnectionManager
интерфейса, который позволяет вам получить доступ к объекту контекста для концентратора.
Дополнительную информацию можно найти в официальной документации.
Ответ №2:
Hub.GetClients исчез в версии 0.4.0.
Из вики теперь вы можете использовать:
IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();
Комментарии:
1. И не забудьте добавить
using SignalR.Infrastructure;
Ответ №3:
Вы можете легко использовать концентратор, выполнив этот 2 шага-
-
Создание экземпляра путем внедрения зависимостей следующим образом-
public class ClassName { ........ ........ private IHubContext _hub; public BulletinSenderController(IConnectionManager connectionManager) { _hub = connectionManager.GetHubContext<McpHub>(); ........ ........ } ............ ............ }
2. Использование hub
объекта, подобного этому-
_hub.Clients.All.onBulletinSent(bulletinToSend);
Больше можно найти здесь .
Пример кода можно найти в этом репозитории git.
Ответ №4:
Посмотрите, как это делается Chat.cs
в SignalR.Samples.Hubs.Chat
из https://github.com/SignalR/SignalR .
Я вижу там, что статические Dictionary<TKey, TValue>
экземпляры создаются вверху, поэтому я полагаю, что они также поддерживаются постоянно, либо Chat
класс является сохраняемым экземпляром (?), Либо этот массив каким-то образом обновляется.
Проверьте это, Дэвид Фаулер, вероятно, был бы лучшим в этом.
Комментарии:
1. Да, я использую образцы SignalR, чтобы попытаться решить эту проблему. Словари статичны, поэтому информация сохраняется в нескольких экземплярах класса, поэтому я надеялся, что смогу просто создать экземпляр Hooking.cs и использовать его, но это не работает
Ответ №5:
Это изменилось в .NET Core 2, теперь вы можете использовать внедрение зависимостей следующим образом:
private readonly IHubContext<MyHub,IMyHubInterface> _hubContext;
public MyController(MyHub,IMyHubInterface hubContext)
{
_hubContext = hubContext;
}
public bool SendViaSignalR()
{
_hubContext.Clients.All.MyClientSideSignalRMethod(new MyModel());
return true;
}