ASP.NET Core Advent Calendar一日目です。内容は直前で変えたのですが、Sessionまわりの話は空いている日のネタとして投下したいと思います。
SignalR もASP.NET Core対応が進んでいます。
ので現時点で動作するアプリをASP.NET Coreで作れるは作れるのですが、必要なライブラリは正式版としてnuget.orgには公開されてはいません。というところが今回のお話です。
ASP.NET Coreの開発用のライブラリはmygetで配布されているようで、今回はこのチャンネルを使います。
Gallery - MyGet - Hosting your NuGet, Npm, Bower and Vsix packages
SignalRでフィルタすると開発が続いているのがわかります。これを参照するにはproject.jsonと同じ階層にNuGet.configを配置します*1。
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <!--To inherit the global NuGet package sources remove the <clear /> line below --> <clear /> <add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="aspnetcore-dev.dotnet.myget.org" value="https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json" /> </packageSources> </configuration>
project.jsonはこんな感じになります。これは.NET Core 1.1を使う場合の設定になります。
{ "name": "SignalRDemo", "version": "1.1.0-*", "dependencies": { "Microsoft.AspNetCore.Diagnostics": "1.1.0-*", "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0-*", "Microsoft.AspNetCore.Server.Kestrel": "1.1.0-*", "Microsoft.AspNetCore.StaticFiles": "1.1.0-*", "Microsoft.AspNetCore.SignalR.Server": "0.2.0-*", "Microsoft.AspNetCore.WebSockets": "0.2.0-*", "Microsoft.Extensions.Logging.Console": "1.1.0-*", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0-*", "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0-*", "Microsoft.Extensions.Configuration.Json": "1.1.0-*", "Microsoft.Extensions.Configuration.CommandLine": "1.1.0-*" }, "tools": { "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview3-final" }, "frameworks": { "netcoreapp1.1": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.1.0-*", "type": "platform" } } } }, "buildOptions": { "emitEntryPoint": true, "preserveCompilationContext": true }, "runtimeOptions": { "configProperties": { "System.GC.Server": true } }, "publishOptions": { "include": [ "wwwroot", "web.config" ] }, "scripts": { "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] }, "tooling": { "defaultNamespace": "RHTE2016SignalRDemo" } }
実はこのサンプルアプリは10月のおわりごろにデモしようとしたのですが、このタイミングではLinux上では.NET Core 1.0では動かなくなってしまって、.NET Core 1.1のPreviewでしか動きませんでした。その辺の経緯はこのあたりのIssueに残っています。
ですが今確認したところ、.NET Core 1.0 (netcoreapp1.0)で動きました。
"frameworks": { "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0-*", "type": "platform" } } } }
というわけで、ここまで記述したらあとはSignalRアプリを書くだけです。Startupクラスはこんな感じに設定します。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace RHTE2016SignalRDemo { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddSignalR(options => { options.Hubs.EnableDetailedErrors = true; }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); app.UseFileServer(); app.UseWebSockets(); app.UseSignalR(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } } } }
Hubはこんな感じ。counterをSignalRでインクリメントして全クライアントにブロードキャストするだけのHub。
using System.Collections.Generic; using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR.Hubs; namespace RHTE2016SignalRDemo.Hubs { [HubName("message")] public class MessageHub : Hub { public static int Count { get; set; } = 0; public void Send() { Clients.All.broadcast(++Count); } public int GetCurrent() { return Count; } } }
Webページは今回はシンプルに静的htmlのみで書いています。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>SignalR</title> </head> <body> <h1>Hello!</h1> <div id="count"></div> <p><button type="button" id="goodbutton">GOOD!</button></p> <script src="/Scripts/jquery-1.8.2.js"></script> <script src="//ajax.aspnetcdn.com/ajax/signalr/jquery.signalr-2.0.3.js"></script> <script src="/signalr/js"></script> <script type="text/javascript"> $(function () { var message = $.connection.message; var counter = $('#count'); $.connection.hub.start(/*{ transport: activeTransport },*/ function () { message.server.getCurrent(function(value) { counter.text(value); }); $('#goodbutton').click(function () { message.server.send().done(function (values) { }); }); }); message.client.broadcast = function (value) { counter.text(value); }; }); </script> </body> </html>
というわけで、正式版ではなく開発版のライブラリにはなりますが、ASP.NET CoreでもSignalRが使えました。Redisを使う版は改めて調査したいと思います。
*1:プロジェクト単位で参照するNuGetを追加する場合