gpt4 book ai didi

c# - 如何将 SignalR 与 Angular 7 应用程序连接起来

转载 作者:太空狗 更新时间:2023-10-29 17:30:29 25 4
gpt4 key购买 nike

我根本无法弄清楚如何从 Angular 建立信号连接。

https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc 使用以下教程

我添加了一个新的 SignalR 2.4.0 项目到 vs2017 中现有的 .Net 4.6 解决方案。

我也有一个 Angular 7我添加了 SignalR 的应用程序打包通过 npm install @aspnet/signalr
现在我试图在客户端和服务器之间建立一个简单的连接,但不知道如何建立初始连接。

我的前端不断抛出异常:

 core.js:15714 ERROR Error: Uncaught (in promise): Error: Cannot send data if the connection is not in the 'Connected' State.

错误:如果连接未处于“已连接”状态,则无法发送数据。

在我的前端搜索组件中,我添加了一些用于测试的字段:

<mat-form-field>
<input matInput placeholder="message" [(ngModel)]="message">
</mat-form-field>
<button mat-button type="button" (click)="sendMessageToServer()"><span>Send</span></button>
<p *ngFor="let m of messages">{{m}}</p>


在我的 ts 文件中:

// import other components/services here..
import { HubConnection, HubConnectionBuilder} from '@aspnet/signalr';

@Component({
selector: 'app-my-search',
templateUrl: './my-search.component.html',
styleUrls: ['./my-search.component.scss']
})
export class MySearchComponent implements OnInit {

public hubConnection: HubConnection;
public messages: string[] = [];
public message: string;

constructor() { }


ngOnInit() {

// SIGNALR MESSAGE HUB
let builder = new HubConnectionBuilder();
this.hubConnection = builder.withUrl('/SynBroadcastHub/BroadcastMessage').build(); // see startup.cs
this.hubConnection.on('notifyUser', (message) => {
this.messages.push(message);
console.log(message);
});
this.hubConnection.start();
}

// signalr, send msg from client
sendMessageToServer() {
this.hubConnection.invoke('MessageToServer', this.message);
this.message = '';
}


}


在 c# 方面,我添加了一个 SignalR Hub Class (v2)文件,BroadcastHub.cs

using Microsoft.AspNet.SignalR;

namespace SynBroadcastHub
{
public class BroadcastHub : Hub
{
/// Message to client
public void BroadcastMessage(string data)
{
Clients.Caller.notifyUser(data);
}


/// Message from client application; broadcast to all clients if requested.
public void MessageToServer(string data, bool notifyAllClients = false)
{
if (notifyAllClients)
{
Clients.All.NotifyAllClients(data);
}
}
}
}


以及 Startup.cs文件 :

using Microsoft.Owin;
using Microsoft.AspNet.SignalR;
using Owin;

[assembly: OwinStartup(typeof(SynBroadcastHub.Startup))]

namespace SynBroadcastHub
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
HubConfiguration cfg = new HubConfiguration();
app.MapSignalR<PersistentConnection>("BroadcastHub/BroadcastMessage");
app.MapSignalR(cfg);
app.MapSignalR();

//app.MapSignalR<NotifyHub>("notify"); ???
}
public override Task OnDisconnected(bool stopCalled)
{
return Clients.All.leave(Context.ConnectionId, System.DateTime.Now.ToString());
}

public override Task OnConnected()
{
return Clients.All.joined(Context.ConnectionId, DateTime.Now.ToString());
}

public override Task OnReconnected()
{
return Clients.All.rejoined(Context.ConnectionId, DateTime.Now.ToString());
}
}
}

最佳答案

我只是花了两天时间试图弄清楚同样的事情。我终于让它工作了,这些是我必须做的几件事:

1) 您注意到使用 @aspnet/signalr .Net 框架的包不正确,这是正确的。您需要 signalr包 ( npm install signalr )。

2)这是整个过程中最关键的部分。 SignalR依赖于 jQuery .你必须包含 jQuery 之前 包括信号脚本。在 angular.json文件,在 scripts 下部分,您需要包括:

"./node_modules/jquery/dist/jquery.js",
"./node_modules/signalr/jquery.signalR.js"



按照那个确切的顺序。在您的项目启动时,它会首先加载 jQuery,然后是 signalR 脚本。

许多其他 stackover 流答案回答了这个错误的问题:
jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file
叫你写 import * as $ from "jquery"在您想要使用 jQuery 的组件中。但是,它是 不是 这样做是正确的。原因是,根据这篇棱 Angular 分明的文章 about global scripts ,使用 import语法会将其包含在 module 中加载并放入 vendor.js通过运行 ng build 创建的文件命令。这是一个问题的原因是因为 jQuery 将首先从您的 angular.json 加载,然后将加载 signalR,然后来自 vendor.js 的模块将重新加载 jQuery 并取消附加所有刚刚从 signalR 附加到 jQuery 的事件。

3) 由于您注意到您使用的是 .Net Core 版本的 signalr,您将无法访问 HubConnectionBuilder尝试在 Angular 组件中实例化新的 HubConnection 时。

相反,当信号脚本被执行时,它会将额外的事件附加到 $在你的代码中。注意:如果你的 ts 文件在构建或编译时出错,请确保你已经包含了 @types/signalr@types/jquery来自 npm

要设置新的集线器连接,请使用 $.hubConnection("your-url-here/signalr") .这将在运行时附加到您服务器的集线器。注意:我将结果存储为一个名为 hubConnection 的变量在我的 Angular 分量中

在您拥有 Hub 类的服务器代码(.cs 文件)上,您需要在类名上方添加: [HubName("YourHubName")] .所以在你的情况下,你的 .cs 文件在顶部看起来像这样:
[HubName("Broadcast")]    
public class BroadcastHub : Hub

您很可能必须将其包含在 .cs 文件的顶部: using Microsoft.AspNet.SignalR.Hubs;
然后在您的 Angular 组件中设置一个代理以附加到您服务器上的该集线器
实例化新的 hubConnection 后的下一行,写:
this.hubConnection.createHubProxy("yourHubName"); .

在您的情况下, this.hubConnection.createHubProxy("broadcast");
创建代理后,您可以附加监听器以监听从服务器发出的事件,或者您可以从 Angular 组件调用服务器函数。

我关注了这个 example在这里学习如何设置调用事件和监听服务器事件。是的,它是 angular 2,但信号器的功能在我的 angular 7 应用程序中仍然一样。

简短回答:使用 proxy.on('eventname')到服务器的事件,并使用 proxy.invoke('eventname')调用从您的 Angular 组件在您的集线器上运行。

最后,您的 cs 文件中的一些注释。在我的 Startup.cs 中,我唯一可以映射信号器的是 app.MapSignalR() .我没有像您那样详细介绍要设置的其他属性,但这可能是导致某些问题的另一个原因?

关于c# - 如何将 SignalR 与 Angular 7 应用程序连接起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54297637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com