Search code examples
javascriptnode.jsangularazureazure-signalr

Failed to complete negotiation with the server - Angular + SignalR


I'm unable to establish a connection using Angular + Azure Functions using Nodejs. I know that the backend works because I created it using the following documentation and tested it with the client URL provided in docs. Messaging was working across multiple clients.

So now I'm trying to get Angular working. I've created a service for signalr in Angular to establish the connection, but I'm getting the errors

enter image description here enter image description here

and on the network tab

enter image description here I also tried replacing this code in service


  private buildConnection = () => {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:7070") //use your api adress here and make sure you use right hub name.
      .build();
  };

with this code

  private buildConnection = () => {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .configureLogging(signalR.LogLevel.Debug)
      .withUrl("http://localhost:7070/api", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
      })
      .build();

per the recommended answer from this post but then it just returns

enter image description here

I've never used SignalR before so I'm trying to piece this together from looking at several tutorials. I appreciate any help!

signalr service

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") //c
      .build();
  };

  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);
    });
  }
}

just like from Reference Docs link above, this is what my azure functions looks like

messages


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

negotiate


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

host.json

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  },
  "Host": {
    "LocalHttpPort": 7070,
    "CORS": "http://localhost:4200",
    "CORSCredentials": true
  }
}

Solution

  • Ok, you can't connect your Angular with the SignalR function because de CORS polity.

    You forgot to configure the CORS on your function. enter image description here

    Try with this configuration.