SignalR (alpha) for ASP.NET Core 2.0

LinuxでSignalRを使いたいと思いググったところ、ちょうどalphaバージョンがリリースされた直後でした。

blogs.msdn.microsoft.com

このBlogのGetting Startedにやり方が書いてあるものの、ちょっとよく分からなかったので、SignalR .NET Core: Realtime cross-platform open web communicationを参考に手順を書いておきます。

channel9.msdn.com

SignalRって何?という方は、こちらをご参照ください。

SignalRサーバー

Visual Studio 2017で、ASP.NET Core Web アプリケーションのプロジェクトを新規作成します。

f:id:matsujirushix:20170929220951p:plain

ASP.NET Core 2.0を選んで、を選択。

f:id:matsujirushix:20170929221052p:plain

出来上がったプロジェクトはこちら。

f:id:matsujirushix:20170929221137p:plain

nugetからMicrosoft.AspNetCore.SignalRをインストールします。このとき、似たような名前があるので注意して選んでください。なお、現在はalphaバージョンなので、プレリリースを含めるをチェックしないと表示されません。

f:id:matsujirushix:20170929221749p:plain

追加されました。

f:id:matsujirushix:20170929221942p:plain

サービスにSignalRを追加します。StartupクラスのConfigureServices()にservices.AddSignalR()を追加してください。そして、Configure()にChatクラスへのルーティングを追加しておきます。

Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSignalR();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSignalR(routes =>
            {
                routes.MapHub<Chat>("chat");
            });

            //app.Run(async (context) =>
            //{
            //    await context.Response.WriteAsync("Hello World!");
            //});
        }

Chatのところのクイックアクションで、Chatクラスを追加します。

f:id:matsujirushix:20170929222320p:plain

Chatクラスを下記のとおり記入します。

Chat.cs

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRCore2
{
    public class Chat : Hub
    {
        public Task Send(string data)
        {
            return Clients.All.InvokeAsync("AddMessage", data);
        }
    }
}

実行して、http://localhost:50031/chatを開いたときにConnection ID requiredと表示されれば正常です。

f:id:matsujirushix:20170929222744p:plain

SignalRクライアント

クライアントからjsファイルやhtmlファイルを開けるよう、StartupクラスのConfigure()にapp.UseFileServer()を追加します。

Startup.cs

    public class Startup
    {
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ...
            app.UseFileServer();
        }

npmコマンドでネットからsignalr-client-1.0.0-alpha1-final.min.jsを取得して、wwwroot/scriptsにコピーします。

npm install @aspnet/signalr-client

f:id:matsujirushix:20170929223337p:plain

mkdir C:\Users\takashi\Desktop\SignalRCore2\wwwroot\scripts
copy node_modules\@aspnet\signalr-client\dist\browser\signalr-client-1.0.0-alpha1-final.min.js C:\Users\takashi\Desktop\SignalRCore2\wwwroot\scripts

wwwrootにindex.htmlを新規作成します。

f:id:matsujirushix:20170929223719p:plain

index.htmlのbodyタグに追加します。

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <input type="text" id="message" />
    <input type="button" id="send" value="send" />

    <ul id="messages"></ul>

    <script src="/scripts/signalr-client-1.0.0-alpha1-final.min.js"></script>
    <script>
       var conn = new signalR.HubConnection('http://localhost:50031/chat');

       conn.on('AddMessage', data => {
           var li = document.createElement('li');
           li.innerText = data;
           document.getElementById('messages').appendChild(li);
       });

       conn.start()
           .then(() => {
               console.log('Started');
           })
           .catch(err => {
               console.log('Err');
           });

       document.getElementById('send').addEventListener('click', evt => {
           var data = document.getElementById('message').value;
           conn.invoke('Send', data);
       });
    </script>
</body>
</html>

結果

実行すると、このとおり!

f:id:matsujirushix:20170929224458p:plain

サンプルコード

github.com