DEV Community

Masui Masanori
Masui Masanori

Posted on

3 3

[ASP.NET Core] Try SignalR 1

Intro

This time, I will try ASP.NET Core SignalR.

I copied a sample project from tutorials.

Environments

  • .NET 5.0.103

For authentications

  • Microsoft.EntityFrameworkCore ver.5.0.4
  • Npgsql.EntityFrameworkCore.PostgreSQL ver.5.0.2
  • Microsoft.AspNetCore.Identity.EntityFrameworkCore ver.5.0.4

package.json

{
    "dependencies": {
        "@microsoft/signalr": "^5.0.4",
        "ts-loader": "^8.0.17",
        "tsc": "^1.20150623.0",
        "typescript": "^4.2.3",
        "webpack": "^5.24.4",
        "webpack-cli": "^4.5.0"
    }
}
Enter fullscreen mode Exit fullscreen mode

SignalR + Webpack + TypeScript

Failed

Because when I don't use JavaScript frameworks or Blazor, I use Webpack and TypeScript to write client-side codes.

So I changed the sample code to fit my develop environments.
(I just changed from the JavaScript code to TypeScript)

But I got an exception.

Uncaught TypeError: Cannot read property 'HubConnectionBuilder' of undefined
    at init (main.page.ts:9)
    at eval (main.page.ts:34)
    at Object../ts/main.page.ts (mainPage.js:259)
    at __webpack_require__ (mainPage.js:282)
    at mainPage.js:322
    at mainPage.js:325
    at webpackUniversalModuleDefinition (mainPage.js:17)
    at mainPage.js:18
Enter fullscreen mode Exit fullscreen mode

Resolve

I took two mistakes.

webpack.config.js

The first one was about "webpack.config.js".

I wrote like below.

webpack.config.js

var path = require('path');
module.exports = {
    mode: 'development',
    entry: {
        'mainPage': './ts/main.page.ts',
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'wwwroot/js'),
        library: 'Page',
        libraryTarget: 'umd'
    }
};
Enter fullscreen mode Exit fullscreen mode

I had to add "devtool: "eval-source-map""

webpack.config.js

var path = require('path');
module.exports = {
    mode: 'development',
    entry: {
        'mainPage': './ts/main.page.ts',
    },
    module: {
...
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    devtool: "eval-source-map",
    output: {
...
    }
};
Enter fullscreen mode Exit fullscreen mode

Import '@microsoft/signalr'

The second one was about import "@microsoft/signalr".
I wrote TS code like below.

main.page.ts

import signalR from '@microsoft/signalr';

function init() {
    const connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
...
}
init();
Enter fullscreen mode Exit fullscreen mode

But I had to change like below.

main.page.ts

import * as signalR from '@microsoft/signalr';

function init() {
    const connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
...
}
init();
Enter fullscreen mode Exit fullscreen mode

Now I can send or receive messages through SignalR.

Authentications

Because the sample doesn't have authentications, everyone can join the chat.
How can I require signing in?

First, I added codes for ASP.NET Core Identity.

After that, I only needed adding "[Authorize]" attribute into "ChatHub" class.

ChatHub.cs

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

namespace SignalrSample.Hubs
{
    [Authorize]
    public class ChatHub : Hub
    {
...
    }
}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Distinguish between clients

The sample sends messages to all clients.

ChatHub.cs

...
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
...
Enter fullscreen mode Exit fullscreen mode

If I don't want to send to myself, what shall I do?

SignalR can distinguish clients.
So I just need changing like below.

ChatHub.cs

...
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.Others.SendAsync("ReceiveMessage", user, message);
        }
    }
...
Enter fullscreen mode Exit fullscreen mode

Resources

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

AWS Security LIVE!

Hosted by security experts, AWS Security LIVE! showcases AWS Partners tackling real-world security challenges. Join live and get your security questions answered.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️