【问题标题】:SignalR Message not sending - AngularSignalR 消息未发送 - Angular
【发布时间】:2020-10-08 19:13:33
【问题描述】:

我正在尝试使用 SignalR 和 Angular 发送消息,但 API 从未在后端受到攻击。根本没有状态代码,因此它永远不会到达 API 端点。集线器连接建立得很好,所以我认为它在执行this.hubConnection.invoke('NewMessage', message); 时会自动到达端点,但它似乎不起作用。我真的是 SignalR 的新手,所以我很感激任何帮助!

消息发送azure函数代码

module.exports = async function (context, req) {
  return {
    "target": "newMessage",
    "arguments": [ req.body ]
  };
};

函数.json

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "signalR",
      "name": "$return",
      "hubName": "chat",
      "direction": "out"
    }
  ]
}

角度服务

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

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

  constructor() {
    this.buildConnection();
    this.startConnection();
  }

  private buildConnection = () => {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:7070/api")
      .build();
  };
  sendMessage(message: SignalViewModel) {
    this.hubConnection.invoke('NewMessage', message);
  }
  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);
    });
  }
}

角度分量

 txtMessage: string = 'd';
  uniqueID: string = new Date().getTime().toString();
  messages = new Array<SignalViewModel>();
  signalRMessage = new SignalViewModel();
  sendMessage(): void {
    if (this.txtMessage) {
      console.log("Executing signalr")
      this.signalRMessage = new SignalViewModel();
      this.signalRMessage.clientuniqueid = this.uniqueID;
      this.signalRMessage.type = "sent";
      this.signalRMessage.message = this.txtMessage;
      this.signalRMessage.date = new Date();
      this.messages.push(this.signalRMessage);
      this.signalRService.sendMessage(this.signalRMessage);
      this.txtMessage = '';
    }

协商功能


module.exports = async function (context, req, connectionInfo) {
  context.res.json(connectionInfo);
};

协商函数的function.json

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "signalRConnectionInfo",
      "name": "connectionInfo",
      "hubName": "chat",
      "direction": "in"
    }
  ]
}

【问题讨论】:

  • 您好,请同时添加您的服务器端集线器代码。
  • 不要认为这是正确的 url "http://localhost:7070/api" 您希望该 url 指向您在启动时设置的中心 url endpoints.MapHub&lt;T&gt;("/URL");
  • 他说The hub connection establishes fine 所以我相信它是为了中心​​。
  • 这是一个控制台日志,显示连接已建立:postimg.cc/WtxcFmbG 另外我还在上面添加了协商连接 azure 功能
  • 您能否在开发人员工具的“网络”选项卡中验证数据是否实际推送到客户端(或者可能在客户端启用日志记录)。查找显示“连接?”的 URL网络内选项卡并检查带有该呼叫的消息,

标签: angular signalr azure-functions


【解决方案1】:

问题是你有"NewMessage",在客户端有大写“N”,在函数上有“newMessage”。

module.exports = async function (context, req) {
  返回 {
    "target": "newMessage", // "n"
    “参数”:[ req.body ]
  };
};
 sendMessage(message: SignalViewModel) {
    this.hubConnection.invoke('NewMessage', message); // "N"
  }

还可以查看documentation,了解无服务器模式下的 Azure SignalR 服务。如您所见,如果您的集线器配置为无服务器模式,则无法从客户端调用方法。

如果您在无服务器模式下使用 Azure SignalR 服务,则无法从客户端调用集线器方法。有关详细信息,请参阅 SignalR 服务文档。 Link

更新:由于您正在使用 Azure Functions 并且需要在无服务器模式下运行 SignalR,如下所示,您无法从客户端调用集线器方法。

【讨论】:

  • 我创建了一个新的 SignalR 实例,它根据您的建议以经典模式运行,不使用无服务器模式,但它返回 postimg.cc/BXdnK88t 如何让它与 Angular 客户端配合使用?我四处寻找这个错误,但还没有找到任何东西让我知道如何克服这个错误。我还在信号器服务中从NewMessage 更新为newMessage
  • 由于您在 Azure Functions 上使用 signalR 进行开发,我相信您的服务器模式需要是无服务器的,如您在此处看到的 (docs.microsoft.com/en-us/azure/azure-signalr/…)。
  • 我不建议你关闭 serverless mod,只是想让你看看文档是怎么说的。
  • 您开启了默认模式,但该模式需要服务器才能运行。
  • 我的错。我想我误解了。你说if your hub is configured to Serverless mode, you can't call methods from client. 如果是这样的话,那么听起来 Angular 不能在无服务器模式下工作。我刚刚恢复到无服务器模式。既然 newMessage 已修复,您有什么建议可以让消息 azure 函数执行吗?目前,当我点击客户端中的按钮调用消息时,天蓝色函数控制台从不显示任何输出。 (从未收到)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 2014-12-16
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多