我有一个监控/日志记录中心,它使用SignalR(2.2.1)和Azure Mobile App进行身份验证。无论ApiController上是否存在MobileAppController属性,即使ApiController不包含集线器调用代码,从浏览器调用/ api / values也会立即杀死我的SignalR集线器。我必须重新启动Web应用程序才能让它再次运行。与此同时,网页将继续尝试连接/重新连接。
条纹控制器看起来像
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
return "Hello World!";
}
}
我在
中设置了WebApi public static void ConfigureMobileApp(IAppBuilder app, IDependencyResolver resolver)
{
HttpConfiguration config = new HttpConfiguration();
config.DependencyResolver = resolver;
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
config.Formatters.Add(new BsonMediaTypeFormatter());
new MobileAppConfiguration()
//.MapApiControllers()
.AddTables(
new MobileAppTableConfiguration()
.MapTableControllers()
.AddEntityFramework()
)
.AddPushNotifications()
.MapLegacyCrossDomainController()
.ApplyTo(config);
// Use Entity Framework Code First to create database tables based on your DbContext
Database.SetInitializer(new MobileServiceInitializer());
MobileAppSettingsDictionary settings = config.GetMobileAppSettingsProvider().GetMobileAppSettings();
if (string.IsNullOrEmpty(settings.HostName))
{
app.UseAppServiceAuthentication(new AppServiceAuthenticationOptions
{
// This middleware is intended to be used locally for debugging. By default, HostName will
// only have a value when running in an App Service application.
SigningKey = ConfigurationManager.AppSettings["SigningKey"],
ValidAudiences = new[] { ConfigurationManager.AppSettings["ValidAudience"] },
ValidIssuers = new[] { ConfigurationManager.AppSettings["ValidIssuer"] },
TokenHandler = config.GetAppServiceTokenHandler()
});
}
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
app.UseWebApi(config);
}
使用
设置SignalR public static void ConfigureSignalR(IAppBuilder app, CustomNinjectDependencyResolver resolver)
{
IKernel kernel = resolver.Kernel;
var connectionManager = resolver.Resolve<IConnectionManager>();
var heartbeat = resolver.Resolve<ITransportHeartbeat>();
var hubPipeline = resolver.Resolve<IHubPipeline>();
kernel.Bind<IConnectionManager>().ToConstant(connectionManager);
kernel.Bind<IUserIdProvider>().To<ZumoUserIdProvider>().InSingletonScope();
var hubConfig = new HubConfiguration
{
Resolver = resolver,
EnableDetailedErrors = true,
EnableJSONP = true,
};
hubPipeline.AddModule(kernel.Get<LoggingHubPipelineModule>());
app.MapSignalR(hubConfig);
}
当我尝试转到/ api / values时,会发生这种情况
Microsoft.Azure.AppService.Authentication Verbose: 0 : Received request: GET https://kamelos-app.azurewebsites.net/api/values
Microsoft.Azure.AppService.Authentication Verbose: 0 : Found 'AppServiceAuthSession' cookie for site 'xxx.azurewebsites.net'. Length: 768.
Microsoft.Azure.AppService.Authentication Verbose: 0 : Authenticated xxx successfully using 'Session Cookie' authentication.
Exception thrown: 'System.Reflection.ReflectionTypeLoadException' in mscorlib.dll
Exception thrown: 'System.Net.WebSockets.WebSocketException' in System.Web.dll
Exception thrown: 'System.Net.WebSockets.WebSocketException' in mscorlib.dll
Exception thrown: 'System.OperationCanceledException' in mscorlib.dll
Exception thrown: 'System.OperationCanceledException' in System.Web.dll
Microsoft.Azure.AppService.Authentication Verbose: 0 : Received request: GET https://kamelos-app.azurewebsites.net/favicon.ico
Microsoft.Azure.AppService.Authentication Verbose: 0 : Exception thrown: 'System.OperationCanceledException' in mscorlib.dll
Found 'AppServiceAuthSession' cookie for site 'kamelos-app.azurewebsites.net'. Length: 768.
Exception thrown: 'System.OperationCanceledException' in mscorlib.dll
Microsoft.Azure.AppService.Authentication Verbose: 0 : Authenticated xxx successfully using 'Session Cookie' authentication.
Exception thrown: 'System.OperationCanceledException' in mscorlib.dll
尝试将SignalR降级为2.1.2无济于事。同样的问题。
更新。如果一个SignalR会话没有进行,我转到/ api / values,输出日志中有WebSocketException,但是,之后进入监控页面,那里不再是SignalR。至于监控代码:
<script type="text/javascript">
$(function () {
function encodeHtml(html) {
// html still emits double quotes so we need to replace these entities to use them in attributes.
return $("<div/>").text(html).html().replace(/\"/g, """);
}
var monitor = $.connection.monitor;
$.connection.hub.logging = true;
monitor.client.logError = function (value) {
$('#logs').prepend('<li class="error">' + encodeHtml(value).replace('\n', '<br/>') + '</li>');
};
monitor.client.logWarn = function (value) {
$('#logs').prepend('<li class="warn">' + encodeHtml(value).replace('\n', '<br/>') + '</li>');
};
monitor.client.logMessage = function (value) {
$('#logs').prepend('<li class="message">' + encodeHtml(value).replace('\n', '<br/>') + '</li>');
};
$.connection.hub.disconnected(function () {
setTimeout(function () {
$.connection.hub.start();
}, 5000);
});
$.connection.hub.start();
});
</script>
但这有效,直到调用/ api / values。所以我认为这不是因为监控代码。此外,当SignalR发生故障时,整个服务器都会失败。从不同的IP地址进入也无法从SignalR获得信号。
如果监控页面没有启动,那么我会看到
Microsoft.Azure.AppService.Authentication Verbose: 0 : Received request: GET https://kamelos-app.azurewebsites.net/api/values
Microsoft.Azure.AppService.Authentication Verbose: 0 : Found 'AppServiceAuthSession' cookie for site 'xxx.azurewebsites.net'. Length: 768.
Microsoft.Azure.AppService.Authentication Verbose: 0 : Authenticated Tim Uy successfully using 'Session Cookie' authentication.
Exception thrown: 'System.Reflection.ReflectionTypeLoadException' in mscorlib.dll
'w3wp.exe' (CLR v4.0.30319: /LM/W3SVC/1848204182/ROOT-2-131345909532020945): Loaded 'D:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Data.Services.Client\v4.0_5.6.2.0__31bf3856ad364e35\Microsoft.Data.Services.Client.dll'. Cannot find or open the PDB file.
05:32:22.128 [25] DEBUG ValuesController - requested /api/values
UPDATE2。
问题是config.DependencyResolver = resolver
。当注释掉时,SignalR不会崩溃。我认为以某种方式运行apiController会导致解析器被转储。
是的,ApiController完成的那一刻,我的CustomNinjectDependencyResolver就是Disposed。为什么这样做?
答案 0 :(得分:1)
事实证明违规行是
config.DependencyResolver = resolver
并且WebApi在调用ApiController后处理解析器。见Why is ASP.NET Web Api's Dependency Resolver being disposed?
&#34; Web API为每个请求调用一次BeginScope()方法 基础结构和Web API将在何时调用IDependencyScope.Dispose() 请求结束。&#34;