Итак, я прочитал все другие вопросы SO по этому поводу, но похоже, что все должно быть настроено правильно. Я запускаю собственное консольное приложение SignalR с одним пустым объявлением концентратора (это для односторонней связи от сервера к подключенным клиентам).
РЕДАКТИРОВАТЬ: Ссылка на проект, в котором воспроизводится проблема - https://dl.dropboxusercontent.com/u/66477739/SignalRTest.zip
В демонстрационном решении 3 проекта:
- SignalRTest.BusinessLogic - Простое консольное приложение, которое публикует сообщение каждые 10 секунд. Эти сообщения никогда не принимаются клиентом. Это имитирует мой уровень бизнес-логики, отправляющий уведомления подключенным клиентам.
- SignalRTest.SelfHost - автономное приложение SignalR + концентратор. Я добавил к концентратору метод «Отправить» только для того, чтобы показать, что все работает, когда клиент вызывает
server.send('message');
, но не работает, когда сервер инициирует сообщение. Если ввести в этом окне консоли и нажать клавишу ВВОД, этот текст будет отправлен в веб-приложение. ЭТО РАБОТАЕТ! - SignalRTest.UI - просто пустое приложение MVC с одной страницей, загружающей необходимые скрипты. Успешно полученное сообщение будет просто записывать вывод консоли, в этом образце никогда не будет никаких изменений пользовательского интерфейса.
PublishStatusHub.cs
public class PublishStatusHub : Hub
{
}
JS
$(document).ready(function () {
$.connection.hub.url = "http://localhost:8080/signalr";
var publish = $.connection.publishStatusHub;
publish.client.addMessage = function (message) {
console.log(message);
};
$.connection.hub.start().done(function() { });
});
Вызов кода из отдельной сборки
var context = GlobalHost.ConnectionManager.GetHubContext<PublishStatusHub>();
context.Clients.All.addMessage("Starting publish...");
Хотя я вижу, что приведенный выше код выполняется (через точки останова), клиентский метод никогда не вызывается.
Я включил ведение журнала SignalR, и никаких исключений не возникает. Кроме того, он никогда не регистрирует входящие сообщения.
Интересно, что я могу получать сообщения, отправленные клиенту, с помощью моего метода Main () в Program.cs в приложении для самостоятельной консоли:
Program.cs
static void Main(string[] args)
{
string url = "http://localhost:8080";
using (WebApp.Start(url))
{
Console.WriteLine("Server running on {0}", url);
while (true)
{
string message = Console.ReadLine();
IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<PublishStatusHub>();
hubContext.Clients.All.addMessage(message);
}
}
}
Теперь, если я наберу в окне консоли и нажму Enter, сообщение будет успешно отправлено клиенту, и оно будет зарегистрировано в окне вывода консоли.
ОДНАКО, если я перенесу этот код в другой файл в том же консольном приложении, а затем вызову его из другой сборки (что является конечной целью), он снова потерпит неудачу:
MessagePublisher.cs
public class MessagePublisher
{
public void Publish(string message)
{
IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<PublishStatusHub>();
hubContext.Clients.All.addMessage(message);
}
}
Вызов кода из отдельной сборки
var messagePublisher = new MessagePublisher();
messagePublisher.Publish("Test message");
Я застрял в том, почему я не могу публиковать сообщения подключенным клиентам из внешних сборок.