太长;没看过:如何在Angular 6中实现强类型的SignalR集线器(自定义方法)?
最终,我正在尝试使用服务和接口在Angular 6中使用强类型SignalR Hub。我先从Hub开始。由于SignalR可以选择现在强类型的命令,我想使用它们来更好地保护数据。我不介意也有办法进行身份验证,但这可能是一个不同时间的故事。
ApHub.cs
using System.Threading.Tasks;
using AckermanPuglisi.Thesaurus;
using Microsoft.AspNetCore.SignalR;
namespace Tinhalo.Hubs {
public class ApHub : Hub<INlgClient> {
private readonly IApContext _apContext;
public ApHub(IApContext apContext) {
_apContext = apContext;
}
public async Task GetTraits() {
await Clients.Caller.GetAllTraits(_apContext.Traits);
}
public async Task GetEmotions() {
await Clients.Caller.GetAllEmotions(_apContext.Emotions);
}
public async Task ConnectionMessage() {
await Clients.Caller.CheckConnection("You are connected");
}
}
}
从那里,我创建SignalR的接口,以获得我需要在Angular中调用的类型化方法。我已经将模型设置在模型文件夹中,但我会忽略其中的细节,因为我不确定它们是否相关。
INlgClient.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AckermanPuglisi.Thesaurus.Data.Graph.Models;
namespace Tinhalo.Hubs {
public interface INlgClient {
Task GetAllTraits(ICharacterTrait[] apContextTraits);
Task GetTrait(ICharacterTrait trait);
Task GetAllEmotions(Emotion[] apContextEmotions);
Task GetEmotion(Emotion emotion);
Task GetTraitEmotions(string traitName);
Task CheckConnection(string connectMessage);
}
}
这些以前的两件事在他们是非打字时肯定有效。之后,我在Angular 6中做了一些事情,即服务(我发现你无法启动()中心连接,直到你定义了window
...否则你得到一个XMLHttpRequest未定义的错误)
signal.service.ts
import { Injectable, Inject, OnInit, AfterViewInit } from '@angular/core';
import { HubConnection, HubConnectionBuilder, JsonHubProtocol } from "@aspnet/signalr";
import { Emotion } from '../models/emotion.model';
import { Trait } from '../models/trait.model';
import * as signalr from '@aspnet/signalr';
import { Subject } from 'rxjs';
@Injectable({
providedIn: "root"
})
export class SignalService {
public aphub: HubConnection;
public hubConnected: any;
constructor(@Inject('BASE_URL') baseUrl: string) {
let options = {
transport: signalr.HttpTransportType.WebSockets
| signalr.HttpTransportType.LongPolling,
AccessTokenFactory: async () => {
// Get and return the access token.
// This function can return a JavaScript Promise if asynchronous
// logic is required to retrieve the access token.
}
};
let protocol = new signalr.JsonHubProtocol();
this.aphub = new signalr.HubConnectionBuilder()
.configureLogging(signalr.LogLevel.Trace)
.withUrl(`${baseUrl}aphub`, options)
.withHubProtocol(protocol).build();
}
}
现在,如果我做的this.aphub.getTraits((traits) => { ... });
相当于hub.invoke('getTraits' ... )
,它会说该方法不是在设计时定义的,而是在运行时检查时出现。这告诉我,我完全需要一个接口 - 我有点了。我认为最大的问题是我可能能够在新类上实现我的自定义方法,但我不知道我必须自定义实现什么,因为私有/内部的东西混合到SignalR HubConnections。
我甚至可能都没有实现正确的对象。
aphub.interface.ts
import { HubConnection } from "@aspnet/signalr";
interface IAphub extends HubConnection {
getTraits(): void;
getTrait(traitName: string): void;
getTraitEmotions(traitName: string): void;
getEmotions(): void;
getEmotion(emotionName: string): void;
connectionMessage(): void;
}
class ApHub implements IAphub {
/* What goes here? */
}
请善待,我对Angular本身很新,但我肯定会得到它的C#部分。我已经在MVC工作了很长一段时间 - Typescript对我来说有点新鲜,但我得到了大部分内容。 SignalR似乎是异步数据的最佳方式,因为它有超过.Caller
,但也有.Broadcast
,它将在以后派上用场。
谷歌在Angular上有很多东西,但是使用Angular 1.x,Angular 2.x以及所有版本混淆(ng-thing vs. ng2-thing vs. ngx-thing plus stuff with $
and $scope
and again with充满了Angular 4.x代码的dumptrucks),我只想找到我的AspNetCore 2.1(为3.0),SignalR @ latest和Angular 6网站的答案。
我曾尝试使用SignalR.exe生成一个接口,但它没有工作说它缺少清单 - 这可能是因为它是一个dotnet核心应用程序。