【问题标题】:Angular not subscribing to SignalR messageAngular 未订阅 SignalR 消息
【发布时间】:2020-07-03 00:41:32
【问题描述】:

我正在尝试订阅我发送的消息,但它在浏览器中一直返回 null

SignalR 连接已经建立,我可以发送消息,但它没有订阅任何更改。这是为什么呢?

SignalR 服务

import { Injectable, EventEmitter } from "@angular/core";
import * as signalR from "@aspnet/signalr";
import { SignalViewModel } from "./signal-view-model";
import { HttpClient, HttpParams } from "@angular/common/http";


@Injectable({
  providedIn: "root"
})
export class SignalRService {
  private hubConnection: signalR.HubConnection;
  signalReceived = new EventEmitter<SignalViewModel>();

  constructor(private http: HttpClient) {
    this.buildConnection();
    this.startConnection();
  }

  private buildConnection = () => {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:7070/api")
      .build();
  }
  sendMessage(message: SignalViewModel) {

    this.http.post('http://localhost:7070/api/messages', message).subscribe(data => console.log(data));
  }
  private startConnection = () => {
    this.hubConnection
      .start()
      .then(() => {
        console.log("Connection Started...");
        this.registerSignalEvents();
      })
      .catch(err => {
        console.log("Error while starting connection: " + err);

        //if you get error try to start connection again after 3 seconds.
        setTimeout(function () {
          this.startConnection();
        }, 3000);
      });
  }

  private registerSignalEvents() {
    this.hubConnection.on("SignalMessageReceived", (data: SignalViewModel) => {
      this.signalReceived.emit(data);
    });
  }
}

信号视图模型

export class SignalViewModel {
  clientuniqueid: string;
  type: string;
  message: string;
  date: Date;
}

组件

  notificationSubscription: Subscription;

  ngOnInit() {

 this.signalRService.signalReceived.subscribe(msg => {
      this.messages.push(msg);
      console.log(this.messages)

    });

//I also tried it like the following, but same issue

 this.notificationSubscription = this.signalRService.signalReceived.subscribe(msg => {
      this.messages.push(msg);
      console.log(this.messages)

    })

...

我怎样才能让它订阅成功?感谢您的帮助!

【问题讨论】:

    标签: angular azure signalr azure-functions


    【解决方案1】:

    您可以尝试这种方法。在 signalR 服务上创建一个 EventEmitter:

    @Output() onSignalRMessage: EventEmitter<any> = new EventEmitter();
    

    并调用私有函数以SignalViewModel接收数据。

    private registerSignalEvents() {
        this.hubConnection.on("SignalMessageReceived", (data: SignalViewModel) => {
          this.newMessage(data as SignalViewModel);
        });
      }
    
    private newMessage(data: SignalViewModel) {
        this.onSignalRMessage.emit(data);
      }
    

    然后在组件上:

    ngOnInit(): void {
      /** Invoked when is received new data*/
      this.signalRService.onSignalRMessage.subscribe((data: SignalViewModel) => {
        console.log(data);
      });
    

    别忘了将signalRService 添加到构造函数中。

    更新 1:运行您的代码后,我可以成功连接到本地 signalR 服务以及 Azure SignalR 服务,并且我正在接收数据。如您所见,问题在于没有连接,而不是接收到的数据。

    您应该看到 Azure 函数出了什么问题。

    我还建议将您的客户端 SignalR 包从现已过时的 @aspnet/signalr 更改为新的 @microsoft/signalr 包。

    【讨论】:

    • 我假设 onNotification 应该是 onSignalRMessage 我添加了 this.signalRService.onSignalRMessage.subscribe((data: SignalViewModel) => { console.log("SIGNALR DATA", data) });但它从未出现在输出中
    • 好的,它显示在服务上了吗?将 console.log 放在 registerSignalEvents` 上。
    • 如果我将它移到服务中也不会显示。如果我没有 console.log 并且我发送了一条消息,那么我会在控制台 postimg.cc/3y09MXMQ 中得到它。我觉得它给我的印象是连接没有建立,但是它不会显示这个postimg.cc/VddffFPJ所以我很困惑哈哈
    • postimg.cc/VddffFPJ 这表示连接成功。您可以做的最后一个测试是删除SignalViewModel 演员表并再次查看console.log。 this.hubConnection.on("SignalMessageReceived", (data) =&gt; { console.log(data); });
    • 不。同样的问题。另外,我使用原始问题中的 http.post 方式将消息发送到服务。我从您的回答中注意到了私有 newMessage 方法,所以这就是我提到它的原因。我没有用它来发送新消息
    【解决方案2】:

    你必须使用 obsarvable,在你的情况下你会有这样的东西:

    为您服务:

      import { BehaviorSubject } from 'rxjs';
    
      // In your declaration
      private source = new BehaviorSubject();
      signalReceived = this.source.asObservable();
    
      private registerSignalEvents() {
        this.hubConnection.on("SignalMessageReceived", (data: SignalViewModel) => {
          this.source.next(data)
        });
      }
    

    在您的组件中:

    ngOnInit() {
        this.signalRService.signalReceived.subscribe(data => console.log(data))
     }
    

    【讨论】:

    • 我将代码添加到服务和组件中,但我仍然收到 null 返回
    • EventEmitter 用于不在服务中的父子组件之间进行通信。如果你想在服务和组件之间共享数据,你必须使用 observables。
    • 我将代码添加到服务中,但private source = new BehaviorSubject(); 不添加参数就无法工作,因此我在声明中添加了 null。它说Expected 1 arguments, but got 0. 我认为这会在订阅更改后转换为一个值,但是当我发送新消息时,我仍然从订阅中获得空值。我也将 ngOnInit 行更改为您的答案中的行。更新的信号器服务:pastebin.com/ejL3KuyW 任何想法为什么我仍然为空?
    • 在 registerSignalEvents 中的 this.source.next(data) 尝试记录数据之前。结果如何?
    • 我在this.source.next(data) 之前在registerSignalEvents() 之前添加了以下行console.log("DATA OUTPUT", data),但是当我从组件发送消息时,控制台根本不会输出数据输出。输出中缺少它
    猜你喜欢
    • 2020-10-26
    • 2020-10-08
    • 2021-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多