DEV Community

Masui Masanori
Masui Masanori

Posted on

[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)