我有一个管理许多工作进程的集线器。我想构建一个UI,让我连接到此集线器并从任何这些工作进程中检索处理日志。本质上,这将是一个想要从另一个客户端获取字符串的客户端。我已经能够将客户端A的请求发送给客户端B,但我不知道如何在该响应中返回任何内容。
我在集线器中有一个简单的方法
public void GetRunLog(int runid)
{
JobRunLog log = null;
JobRunClient client = this.GetClientByRunID(runid);
if(client != null)
{
var rawlog = Clients.Client(client.ConnectionID).GetRunLog();
log = JsonConvert.DeserializeObject<JobRunLog>(rawlog);
Clients.Client(Context.ConnectionId).GetRunLog(log);
}
}
客户端会收到此请求,但我不知道如何让它返回一个值,以便var rawlog
实际包含某些内容。目前,这是我能想到的最好的解决方法。
myHubProxy.On("GetRunLog", (uiconnectionid) =>
{
string connectionid = uiconnectionid;
myHubProxy.Invoke("ReturnRunLog", run.ID, run.Log, connectionid).ContinueWith(task => {});
});
然后,这将使工作者客户端在单独的请求中发送回记录,并引用已请求日志的客户端,但它实际上并未向初始请求返回respnonse。我无法看到实现这一目标的方法。而不是使用Invoke,我如何直接将对象返回到发起请求的集线器上的方法?
答案 0 :(得分:1)
不幸的中心doesn't keeps it's state:
由于Hub类的实例是瞬态的,因此您无法使用它们 保持状态从一个方法调用到下一个。每一次 服务器接收来自客户端的方法调用,一个新的实例 Hub类处理消息。通过多重维持状态 连接和方法调用,使用一些其他方法,如a 数据库,或Hub类上的静态变量,或其他类 这不是来自Hub。
尝试将逻辑移动到单独的类中,并将实例对象存储在与连接ID相关的静态字典中(不要忘记清除它)。 Whenewer呼叫来到Hub,它将它重新分配到适当的实例,
这是简化的样本
public class TestingLogHub : Hub
{
public static readonly Dictionary<string, TestInstance> Instances =
new Dictionary<string, TestInstance>();
public void SetParameter(string value)
{
Instances[Context.ConnectionId].ContinueWith(value);
}
...
}
public class TestInstance : IDisposable
{
public TestInstance(string basePath, IHubContext host, string connectionId)
{...
}
public void ContinueWith(string value)
{
if (_nextAction == null)
{
FinishExecution();
}
else
{
try
{
_nextAction(value);
}
catch (Exception exception)
{
Error(exception.Message);
FinishExecution();
}
}
}
public void RequestParameterFor(Action<string> action, string parameter, string defaultValue = null)
{
_nextAction = action;
_host.Clients.Client(_connectionId).requestParameter(parameter, defaultValue??GetRandomText());
}
}
因此,当Instance启动时,它正在做一些工作,但目前它需要一些输入它执行RequestParameterFor
设置下一个要执行到实例状态的函数并等待{{1的下一次调用}}
这是一个通用示例,在您的情况下,您可以发回一个对象并将其提供给实例,并且可以在该请求结束时处置该实例,如果这是唯一需要的调用