【发布时间】:2017-03-22 06:28:23
【问题描述】:
我有一个使用 SignalR (2.2.1) 和 Azure 移动应用进行身份验证的监控/日志记录中心。无论 ApiController 上是否存在 MobileAppController 属性,即使 ApiController 不包含集线器调用代码,从浏览器调用 /api/values 也会立即终止我的 SignalR 集线器。我必须重新启动网络应用程序才能让它再次工作。同时,网页将继续尝试连接/重新连接。
条带化的控制器看起来像
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
更新 2。
问题是config.DependencyResolver = resolver。当这被注释掉时,SignalR 不会崩溃。我认为以某种方式运行 apiController 会导致解析器被转储。
是的,ApiController 完成的那一刻,我的 CustomNinjectDependencyResolver 就被释放了。为什么会这样?
【问题讨论】:
-
at first call, I do get a "Hello message" showing up in my SignalR logging clients (javascript webpages). However, immediately afterwards SignalR calls no longer work.请分享您在 html 网页中使用的代码,以建立与 hub 的连接。如果您从 API 控制器操作调用 hub 方法向客户端推送通知,请分享调用 hub 方法的代码 sn-ps。 -
试一试:从你的 ApiController 中移除 MobileAppController(它没有多大作用)。它仍然会杀死您的 SignalR 吗?如果是这样,这不是 azure-mobile-services 问题。 Azure 移动应用不再处理 SignalR。
-
Fred,你有 bitbucket 用户名吗?我可以和你分享回购。这有点复杂,因为集线器是由记录器调用的。
-
Adrian,确实它被调用 ApiController(没有 MobileAppController)杀死了。我会相应地更改标题。
-
问题是config.DependencyResolver = resolver;
标签: c# asp.net signalr azure-web-app-service