我用ASP.NET Core6和SignalR写了一个聊天程序,不幸的是,当我运行它时,我得到了一个错误

未定义SignalR

在浏览器控制台中.

值得一提的是,我用ASP.NET Core 2.1用相同的代码编写了相同的程序,并且运行正常.

Chat.js代码:

"use strict";
var chatterName = "Visitor";

var dialogEL = document.getElementById('chatDialog');

//Initialize SignalR
var connection = new signalR.HubConnectionBuilder()
    .withUrl('/chatHub')
    .build();

connection.on('ReceiveMessage', renderMessage);

connection.onclose(function () {
    onDisconnected();
    console.log('ReConnecting in 5 Second ...');
    setTimeout(startConnection, 5000);
});

function startConnection() {
    connection.start().then(onConnected).catch(function (err) {
        console.log(err);
    });
}

function onDisconnected() {
    dialogEL.classList.add('disconnected');
}

function onConnected() {
    dialogEL.classList.remove('disconnected');

    var messageTextBox = document.getElementById('messageTextBox');
    var connectingText = document.getElementById('connectingText');
    messageTextBox.focus();
    connectingText.style.visibility = "hidden";

    connection.invoke('SetName', chatterName);
}

function ready() {
    var chatForm = document.getElementById('chatForm');
    chatForm.addEventListener('submit',
        function (e) {
            e.preventDefault();
            var text = e.target[0].value;
            e.target[0].value = '';
            sendMessage(text);
        });

    var welcomePanelFormEL = document.getElementById('chatWelcomePanel');
    welcomePanelFormEL.addEventListener('submit', function (e) {
        e.preventDefault();

        var name = e.target[0].value;
        if (name && name.length) {
            welcomePanelFormEL.style.display = 'none';
            chatterName = name;
            startConnection();
        }
    });

}

function sendMessage(text) {
    if (text && text.length) {
        connection.invoke('SendMessage', chatterName, text);
    }
}

function renderMessage(name, time, message) {
    var nameSpan = document.createElement('span');
    nameSpan.className = 'name';
    nameSpan.textContent = name;

    var timeSpan = document.createElement('span');
    timeSpan.className = 'time';
    var timeFriendly = moment(time).format('H:mm');
    timeSpan.textContent = timeFriendly;

    var headerDiv = document.createElement('div');
    headerDiv.appendChild(nameSpan);
    headerDiv.appendChild(timeSpan);

    var messageDiv = document.createElement('div');
    messageDiv.className = 'message';
    messageDiv.textContent = message;

    var newItem = document.createElement('li');
    newItem.appendChild(headerDiv);
    newItem.appendChild(messageDiv);

    var chatHistory = document.getElementById('chatHistory');
    chatHistory.appendChild(newItem);
    chatHistory.scrollTop = chatHistory.scrollHeight - chatHistory.clientHeight;
}

document.addEventListener('DOMContentLoaded', ready);

program.cs代码:

using ChatApp;
using ChatApp.Services;
using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();
builder.Services.AddSingleton<IChatRoomService, InMemoryChatRoomService>();

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
    options.LoginPath = "/Login";
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
}

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(route =>
{
    route.MapHub<ChatHub>("/chatHub"); //Hub Available from this URL
    route.MapHub<AgentHub>("/agentHub"); //Hub Available from this URL
});

app.MapRazorPages();

app.Run();

chatHub.cs代码:

using ChatApp.Models;
using ChatApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;

namespace ChatApp
{
    public class ChatHub : Hub
    {

        private readonly IChatRoomService _chatRoomService;
        // we want use it to when someone message => Support Admin Alerted and can answer Message => in other meaning referesh admin panels chat
        private readonly IHubContext<AgentHub> _agentHub;

        public ChatHub(IChatRoomService chatRoomService, IHubContext<AgentHub> agentHub)
        {
            _chatRoomService = chatRoomService;
            _agentHub = agentHub;
        }

        public override async Task OnConnectedAsync()// first client connect hub call this method first
        {
            // If User Connected => User is SupportAdmin
            if (Context.User.Identity.IsAuthenticated)
            {
                await base.OnConnectedAsync();
                return;
            }

            var roomId = await _chatRoomService.CreateRom(Context.ConnectionId);
            await Groups.AddToGroupAsync(Context.ConnectionId, roomId.ToString());//Add peopel to groups for Private Chat

            await Clients.Caller.SendAsync("ReciveMessage", "Hamed Support", DateTimeOffset.UtcNow, "How can we Help you?");// send message first time when somone connect to hub

            await base.OnConnectedAsync();
        }

        //Ali
        //Reza
        //Hamed
        //...
        public async Task SendMessage(string name, string text)
        {
            var roomId = await _chatRoomService.GetRoomForConnectionId(Context.ConnectionId);
            var message = new ChatMessage
            {
                SenderName = name,
                SendAt = DateTimeOffset.Now,
                Text = text
            };

            await _chatRoomService.AddMessage(roomId, message);

            //await Clients.All.SendAsync("ReciveMessage",message.SenderName, message.SendAt,message.Text);
            await Clients.Group(roomId.ToString()).SendAsync("ReceiveMessage", message.SenderName, message.SendAt, message.Text);
        }

        //Create Group for Connected User
        public async Task SetName(string visitorName)
        {
            var roomName = $"Chat With {visitorName} from the Web";
            var roomId = await _chatRoomService.GetRoomForConnectionId(Context.ConnectionId);

            await _chatRoomService.SetRoomName(roomId, roomName);
            await _agentHub.Clients.All.SendAsync("ActiveRooms", await _chatRoomService.GetAllRooms()); //message to all online Support Admins
        }

        //we want Login and Logout SupportAdmins:
        [Authorize]
        public async Task JoinRoom(Guid roomId)
        {
            if (roomId == Guid.Empty)
                throw new ArgumentException("Invalid Room ID");

            await Groups.AddToGroupAsync(Context.ConnectionId, roomId.ToString());
        }

        [Authorize]
        public async Task LeaveRoom(Guid roomId)
        {
            if (roomId == Guid.Empty)
                throw new ArgumentException("Invalid Room ID");

            await Groups.RemoveFromGroupAsync(Context.ConnectionId, roomId.ToString());
        }
    }
}

我把ignalr.js文件相关的脚本放在html代码里,也把ignalr.js文件放在wwwroot文件夹的js和lib文件夹中的不同位置,也通过客户端库安装了ignalr.js,但程序还是不能运行

index.cshtml加价:index.cshtml加价:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<link href="~/css/chat.css" rel="stylesheet" />
@section Scripts
    {
    <script src="~/js/Chat.js"></script>
    <script src="~/js/signalr/dist/browser/signalr.js"></script>
}

<div id="chatDialog" title="Chat With Support" class="disconnected">
    <div id="chatWelcomePanel">
        <h3>Have a question ?</h3>
        <form id="chatConnectForm">
            <input class="form-control" type="text" placeholder="Enter Your Name" />
            <input type="submit" class="btn btn-info" value="Connect" />
        </form>
    </div>
    <div id="chatConnectingInfo">
        <strong id="connectingText">Connecting ...</strong>
    </div>
    <div id="chatMainPanel">
        <ul id="chatHistory"></ul>
        <div id="bottomPanel">
            <div class="row">
                <form id="chatForm">
                    <div class="col-md-8">
                        <input id="messageTextBox" class="form-control" type="text" placeholder="Type a Message" />
                    </div>
                    <div class="col-md-2">
                        <input type="submit" class="btn btn-success" value="Send" />
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

如果需要,您可以通过链接github访问在GitHub中编写的代码

谢谢你抽出时间来帮助我?

推荐答案

我能看到这里正在发生的两件事.

第一个是脚本的顺序,所以try 首先定义SignalR,然后加载chat.js

@section Scripts
    {
    <script src="~/js/signalr/dist/browser/signalr.js"></script>
    <script src="~/js/Chat.js"></script>
    
}

然后,确保您正在使用的signalr.js与您之前使用的相同.

Explanation:

发生的情况是,您的代码在这里的Java脚本中失败了,其中没有定义signalR.

//Initialize SignalR
var connection = new signalR.HubConnectionBuilder()
    .withUrl('/chatHub')
    .build();

Csharp相关问答推荐

.NET最小API映射将T参数列表为[FromQuery]

下拉图片点击MudBlazor

. NET 8 HttpClient post参数将其情况更改为camel'

AsNoTrackingWithIdentitySolutions()似乎不起作用?

从Blob存储中提取tar.gz文件并将提取结果上载到另一个Blob存储

返回TyedResults.BadRequest<;字符串>;时问题详细信息不起作用

查找表中的模式

如何使用MoQ模拟Resources GroupCollection?

如何在VS代码中为C#DotNet配置.json选项以调试内部终端的控制台应用程序

如何在我的C#应用程序中设置带有reactjs前端的SignalR服务器?

将FileStream的特定部分作为字节数组读取

在使用AWS SDK for.NET时,如何判断S3是否已验证我的对象的校验和?

是否可以在Entity Framework Core中使用只读 struct 作为拥有实体?

在等待OnGetAsync时打开Razor Page显示微调器

Visual Studio 17.8.0制表符自动完成问题--三缩进

为什么Swashbakle/Swagger在参数中包含变量名?

Linq SELECT的多条指令

映射器-如何映射到多个实体

无效的Zip文件-Zip存档

使用SQL Server 2022+时,我是否必须将代码从SqlConnection类对象中迁移出来?