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"
}
}
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
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'
}
};
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: {
...
}
};
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();
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();
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
{
...
}
}
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);
}
}
...
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);
}
}
...
Top comments (0)