- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试改进我的应用程序,这将需要从 C# 而不是 javascript 调用集线器。在我的应用中添加任务的当前工作流程是:
我想要做的是绕过从我的 AngularJS Controller 调用集线器的方法,并直接从我的 API Controller 方法调用它。
这是我的集线器目前的样子:
public class TaskHub : Hub
{
public void InsertTask(TaskViewModel task)
{
Clients.Caller.onInsertTask(task, false);
Clients.Others.onInsertTask(task, true);
}
}
关于这个主题有很多 SO 线程,但我读过的所有内容都会让我将以下代码添加到我的 API Controller :
var hubContext = GlobalHost.ConnectionManager.GetHubContext<TaskHub>();
hubContext.Clients.All.onInsertTask(task);
这有很多问题。首先,我希望客户端广播调用存在于单个类中,而不是直接从我的 API Controller 调用。其次,hubContext
是 IHubContext
的实例,而不是 IHubCallerConnectionContext
。这意味着我只能访问所有客户端,无法像我目前所做的那样向 Caller
和 Others
广播不同的响应。
有没有办法真正从 C# 调用集线器的方法,并且理想情况下,可以访问不同的调用方选项?理想情况下,我能够从我的 API Controller (或者更好的是,使用 DI 的解决方案)中像下面这样简单地做一些事情:
var taskHub = new TaskHub();
taskHub.InsertTask(task);
提前致谢。
解决方案
为了后代,我想我会按照 Wasp 的建议包含我的完整解决方案。
首先,我修改了我的 javascript (AngularJS) 服务以在 API 调用的自定义请求 header 中包含 SignalR 连接 ID,在本例中为 INSERT:
var addTask = function (task) {
var config = {
headers: { 'ConnectionId': connection.id }
};
return $http.post('/api/tasks', task, config);
};
然后,在执行适用的 CRUD 操作后,我从我的 API Controller 中的请求中检索了连接 ID,然后调用了我的集线器:
public HttpResponseMessage Post(HttpRequestMessage request, [FromBody]TaskViewModel task)
{
var viewModel = taskAdapter.AddTask(task);
var connectionId = request.Headers.GetValues("ConnectionId").FirstOrDefault();
TaskHub.InsertTask(viewModel, connectionId);
return request.CreateResponse(HttpStatusCode.OK, viewModel);
}
我的集线器看起来像这样,我现在只使用从我的 API Controller 调用的静态方法:
public class TaskHub : Hub
{
private static IHubContext context = GlobalHost.ConnectionManager.GetHubContext<TaskHub>();
public static void InsertTask(TaskViewModel task, string connectionId)
{
if (!String.IsNullOrEmpty(connectionId))
{
context.Clients.Client(connectionId).onInsertTask(task, false);
context.Clients.AllExcept(connectionId).onInsertTask(task, true);
}
else
{
context.Clients.All.onInsertTask(task, true);
}
}
}
如您所见,我的集线器方法中有一个条件语句来处理集线器调用不是从我的应用程序的客户端部分启动的情况。如果外部应用程序/服务调用了我的 API,就会出现这种情况。在这种情况下,SignalR 连接和当然“ConnectionId” header 值将不存在。不过,就我而言,我仍然想为所有连接的客户端调用 onInsertTask
方法,通知它们数据更改。这永远不应该发生,但为了完整起见,我只是将其包括在内。
最佳答案
为了真正调用集线器方法,就像您调用它一样,您必须连接到它,并通过该连接调用。通过调用不同的东西(你的 API)你不能做那种调用,因此你必须求助于服务器启动广播功能,它本质上不知道Caller
是因为没有 SignalR 的调用者。
也就是说,如果调用 API 的客户端(无论是 Javascript 还是 C#)在执行调用时已经连接到集线器,则您始终可以装饰您对 API 的调用集线器连接的 connectionId
(按查询字符串、按 header ...)。如果您的 API 收到该信息,它就可以模拟 Caller
API
Clients.Client(connectionId)
它可以为 Others
做同样的事情
Clients.AllExcept(connectionId)
在 IHubContext
实例上。检查official docs .
然后,您可以按照 DDan 的建议,以一种方便的集中方式封装 IHubContext
用法,或者甚至对其进行一些重组,使其更容易与 DI 兼容。
关于c# - SignalR:如何从服务器/C# 真正调用集线器的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31169509/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!