【问题标题】:Strongly-Typed SignalR Hub in Angular 6Angular 6 中的强类型 SignalR Hub
【发布时间】:2018-08-19 20:16:38
【问题描述】:

太长了;没看过: 如何在 Angular 6 中实现强类型 SignalR 集线器(自定义方法)?


最终,我尝试使用服务和接口在 Angular 6 中使用强类型 SignalR 集线器。我先从 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) =&gt; { ... }); 相当于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,稍后会派上用场。

Google 在 Angular 上有很多东西,但是 Angular 1.x、Angular 2.x 和所有版本控制混乱(ng-thing vs. ng2-thing vs. ngx-thing 加上 $ $scope 和装满 Angular 4.x 代码的自卸车),我只想为我的 AspNetCore 2.1(将是 3.0)、SignalR@latest 和 Angular 6 网站找到答案。


我尝试使用 SignalR.exe 生成一个接口,但它没有工作,说它缺少清单 - 这可能是因为它是一个 dotnet 核心应用程序。

【问题讨论】:

  • 我建议您尝试将 TLDR 版本与实际问题放在一起。我已经略过了这个问题,但您唯一的问题是评论What does here?
  • 添加了顶部 - 我原以为标题会是 TL;DR。

标签: c# angular typescript asp.net-core-signalr


【解决方案1】:

我不知道是否可以帮助你,但我已经在 angular6 中创建了一个样板来使用 signalR。

您可以尝试理解我存储库中的代码,我尽量让代码更简单。

随意克隆或询问

FrontEnd

BackEnd

在启动前端之前,您需要遵循以下命令:

  • npm 安装
  • npm install @angular/cli

要运行项目,只需键入:

  • ng 服务

要启动后端,您需要遵循以下命令:

  • dotnet 恢复
  • dotnet 监视运行

我想我得到了你想要的,我猜你想在前面的集线器(背面)中映射方法,对吧?

【讨论】:

  • 是的,我希望能够调用signal.aphub.getTrait() 而不是signal.aphub.invoke('getTrait, ...)
  • 终于看完了。您提供的后端没有 Hub 接口,仍然使用 await Clients.All.SendAsync("getMessage", user.id, user.name, message); 对于我的示例代码,我使用的是 Hub 并且 INlgClient 上面有自定义方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多