我有一个SignalR Class
,其中包含我的SignalR服务器从启动服务器到提供命令之类的所有逻辑。对于扩展到Presenter Class
的模块,我也有一个SignalR Class
,所以我可以从那个模块开始,也可以在那里单独启动。我现在关心的是如何将某种命令发送到Hub Class
的子项SignalR Class
?
这里发生的是,如果我收到来自客户的对SendCommand
的呼叫,我会将其传递给Presenter Class
进行进一步处理,然后需要返回到{{1 }}之后的Hub Class
的子代。
我最初的想法是在Signal Class
的根上创建一个Static EventHandler
,然后在其SignalR Class
子代的构造函数中实现。但是,事实证明这不是一个好主意,因为由于服务器的EventHandler,客户端正在接收重复的消息,因为我已经阅读到“ SignalR为每个请求创建一个新的中心实例” 。还有其他可行的方法可以以不同的实现方式来完成我想要的事情。
以下是基于我的模式的示例代码:
SignalR.cs
Hub Class
ModulePresenter.cs
[assembly: OwinStartup(typeof(MY_NAMESPACE_HERE.SignalR.Startup))]
public class SignalR
{
private static event EventHandler<CommandCompletedEventArgs> CommandCompleted;
public static void OnCommandCompleted(CommandCompletedEventArgs e)
{
CommandCompleted?.Invoke(typeof(SignalR), e);
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
public class MyHub : Hub
{
public static event EventHandler<CommandSentEventArgs> CommandSent;
public MyHub()
{
// this -= proved to not be effective as there's multiple instance of the MyHub class
// one after the other, and is not being disposed of
CommandCompleted -= MyHub_CommandCompleted;
CommandCompleted += MyHub_CommandCompleted;
}
private static void MyHub_CommandCompleted(object sender, CommandCompletedEventArgs e)
{
// the client receives multiple messages from this command due to the instance multiplying per request together with event assignment duplicates
Clients.Client(e.ConnectionId).BroadcastResponse(e.Response);
}
protected void OnCommandSent(CommandSentEventArgs e)
{
CommandSent?.Invoke(this, e);
}
public override Task OnConnected()
{
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
return base.OnDisconnected(stopCalled);
}
public void SendCommand(string commandJson)
{
var command = Utilities.DeserializeJson<Command>(commandJson);
switch (command.key)
{
case "request-token":
OnCommandSent(new CommandSentEventArgs(ConnectionId, command));
break;
default:
Clients.Client(Context.ConnectionId).addMessage("Unregistered command received: ", commandJson);
break;
}
}
}
}