Asp.net 信号器:连接id的格式不正确。会话到期时如何处理?

Asp.net 信号器:连接id的格式不正确。会话到期时如何处理?,asp.net,asp.net-mvc,asp.net-mvc-4,signalr,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Signalr,我提出了一个众所周知的信号器问题,当谷歌搜索“连接id的格式不正确”时会给出多个结果。但是我找不到适合我需要的解决方案。所有建议的解决方案都是相同的:客户端javascript中的停止信号器。然而,我需要的是以某种方式停止或处理服务器端的错误 示例:用户登录,signer启动,一切正常,他单击logout(就在logout I覆盖javascript事件并停止signer之前)。没有错误 另一个示例:用户登录,信号器启动,用户等待会话结束一段时间。他点击了一些东西,他被扔到登录页面。但是,Sig

我提出了一个众所周知的信号器问题,当谷歌搜索“连接id的格式不正确”时会给出多个结果。但是我找不到适合我需要的解决方案。所有建议的解决方案都是相同的:客户端javascript中的停止信号器。然而,我需要的是以某种方式停止或处理服务器端的错误

示例:用户登录,signer启动,一切正常,他单击logout(就在logout I覆盖javascript事件并停止signer之前)。没有错误

另一个示例:用户登录,信号器启动,用户等待会话结束一段时间。他点击了一些东西,他被扔到登录页面。但是,Signal现在注意到用户的身份已更改,并抛出此错误连接id的格式不正确。再加上一些这样的情况,我让我的IIS工作人员在100%的CPU下工作,从而导致服务器崩溃。一个稍加修改的示例包括向服务器发出ping信号,并再次看到会话已结束,从而引发异常

我应该如何处理这个问题?是否有一种方法可以从服务器端停止特定客户端的信号器?或者是别的什么?也许我能让信号员停止依赖身份?我相信人们一定已经以某种方式解决了这个问题。我在我的项目中使用表单身份验证和MVC4。SignalR的版本是1.0.0。我知道它不是最新的,但我怀疑如果它是最新的会有什么好处。或者有人有证据证明我错了

我正在从IIS日志中添加错误信息,以防万一:

Exception information: 
    Exception type: InvalidOperationException 
    Exception message: 

Server stack trace: 
   at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken)
   at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
   at Microsoft.AspNet.SignalR.Owin.CallHandler.Invoke(IDictionary`2 environment)
   at Microsoft.AspNet.SignalR.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2 environment)
   at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()
   at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object extraData)

Exception rethrown at [0]: 
   at Microsoft.Owin.Host.SystemWeb.Utils.<>c__DisplayClass1.<GetRethrowWithNoStackLossDelegate>b__0(Exception ex)
   at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)



Request information: 
    Request URL: http://example.com:port/signalr/abort?transport=serverSentEvents&connectionToken=0D8V3TwV78z1cU7_kbQGaSjZH1r_w4eGkkFPRftDiZXPJjbEZmXEluSOkvzVBDRQOGWzVPGfeCKdsvEUwhzb07-Kph-pJ3oog_ydjvsRSnoXqDnYZkPXwJgPrFsFYtmpFDKe0hOvHS7ZxApQF_4fbw2 
    Request path: /signalr/abort 
    User host address: A.B.C.D 
    User:  
    Is authenticated: False 
    Authentication Type:  
    Thread account name: IIS APPPOOL\DefaultAppPool 

Thread information: 
    Thread ID: 63 
    Thread account name: IIS APPPOOL\DefaultAppPool 
    Is impersonating: False 
    Stack trace:    at Microsoft.Owin.Host.SystemWeb.Utils.<>c__DisplayClass1.<GetRethrowWithNoStackLossDelegate>b__0(Exception ex)
   at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
异常信息:
异常类型:InvalidOperationException
异常消息:
服务器堆栈跟踪:
位于Microsoft.AspNet.signal.PersistentConnection.GetConnectionId(主机上下文,字符串connectionToken)
位于Microsoft.AspNet.signal.PersistentConnection.ProcessRequest(主机上下文)
位于Microsoft.AspNet.signal.Owin.CallHandler.Invoke(IDictionary`2环境)
位于Microsoft.AspNet.signal.Owin.Handlers.HubDispatcherHandler.Invoke(IDictionary`2环境)
在Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute()中
位于Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest(HttpContextBase httpContext、AsyncCallback回调、对象extraData)
在[0]处重试异常:
在Microsoft.Owin.Host.SystemWeb.Utils.c__;u DisplayClass1.b__u0上(异常示例)
位于Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult结果)
在System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()中
在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值&同步完成)
请求信息:
请求URL:http://example.com:port/signalr/abort?transport=serverSentEvents&connectionToken=0D8V3TwV78z1cU7_kbQGaSjZH1r_w4eGkkFPRftDiZXPJjbEZmXEluSOkvzVBDRQOGWzVPGfeCKdsvEUwhzb07-Kph-pJ3oog_ydjvsrsnoxqdnyzkpxwjgprfsffytmpdfdke0hovhs7zxapqf_4fbw2
请求路径:/signar/abort
用户主机地址:A.B.C.D
用户:
已验证:False
身份验证类型:
线程帐户名称:IIS APPPOOL\DefaultAppPool
线程信息:
线程ID:63
线程帐户名称:IIS APPPOOL\DefaultAppPool
是模仿:假
堆栈跟踪:位于Microsoft.Owin.Host.SystemWeb.Utils.c\u DisplayClass1.b\u 0(异常示例)
位于Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End(IAsyncResult结果)
在System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()中
在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值&同步完成)

您可以从中找到一个很好的解释。似乎您无法以某种方式使用与Signaler的会话。
我希望它能对您有所帮助。

这将对您的会话管理有所帮助

只要“大声思考”,如果问题仅仅是因为会话过期,您可能希望在会话在服务器上结束时尝试拦截,并向所有受影响的客户端广播一条消息(为此添加的逻辑),要求它们明确断开连接,避免它们冲击您的服务器。我猜您的会话与身份验证绑定,因此无论如何都必须进行登录,这样您就可以在之后重新连接Signaler。有道理吗

您还可以让客户端超时在N-1分钟后过期,其中N是会话的持续时间。让那一个力断开。如果服务器上发生的事情使时间窗口移动,则可以使用信号器本身更新超时本身


这两种解决方案都是务实、快速和肮脏的,以使信号员和会话保持一致。

谢谢。自从您的回复以来,我一直在阅读许多关于禁用会话的文章。非常有趣。我会看看进展如何,如果有任何进展,我会更新。你使用Redis/SQL Server扩展吗?@MosheL不,我没有。从未真正听说过这些。会话是否会丢失,从而导致
n-1
方法失败?会话结束时如何拦截?没有触发的事件(至少我不知道),会话结束的真正效果是当用户向服务器发出某种请求时。服务器端,您有一个很好的旧会话结束事件,这可能会有所帮助。在该事件中,您可以通知相关客户端并要求断开连接。在任何其他情况下,我们可以假设会话是活动的,因此thr N-1策略应该有效。当然,对于可能在SignalR之外执行的任何异步请求,都必须重置客户端超时。正如我所说,这是一个想法,我从来没有遇到过这个问题,我不是100%确定它会起作用,但它看起来有一些潜力可以探索。我不认为第一个链接是问题的解决方案,它只是在标题中有一个名称“session”。也许我错了?第二个也没有。