web-dev-qa-db-ja.com

Angular / SignalRエラー:サーバーとのネゴシエーションを完了できませんでした

サーバーにSignalRを使用し、クライアントにAngularを使用しています...クライアントを実行すると、次のエラーが表示されます。

zone.js:2969 OPTIONS https://localhost:27967/chat/negotiate 0 ()

Utils.js:148 Error: Failed to complete negotiation with the server: Error

Utils.js:148 Error: Failed to start the connection: Error

私はそれがCORSで何かだと推測しています...私は簡単なチャットアプリケーションを実装しようとしています。 SignalRの最新バージョンを使用しています。

これは、私がフォローしているチュートリアルのコードを含むgithubです。 SignalRチャットチュートリアル

これが私のスタートアップです

    using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace signalrChat
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.Microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
            {
                builder
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .WithOrigins("http://localhost:4200");
            }));

            services.AddSignalR();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("CorsPolicy");

            app.UseSignalR(routes =>
            {
                routes.MapHub<ChatHub>("/chat");
            });
        }
    }
}

そして、ここに私のクライアントがあります:

    import { Component, OnInit } from '@angular/core';
import { HubConnection, HubConnectionBuilder } from '@aspnet/signalr';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  private hubConnection: HubConnection;

  nick = '';
  message = '';
  messages: string[] = [];

  ngOnInit() {
    this.nick = window.Prompt('Your name:', 'John');

    this.hubConnection = new HubConnectionBuilder().withUrl('https://localhost:27967/chat').build();

    this.hubConnection
    .start()
    .then(() => console.log("Connection Started!"))
    .catch(err => console.log("Error while establishing a connection :( "));

    this.hubConnection.on('sendToAll', (nick: string, receiveMessage: string) => {
      const text = `${nick}: ${receiveMessage}`;
      this.messages.Push(text);
    })
  }

  public sendMessage(): void {
    this.hubConnection
    .invoke('sendToAll', this.nick, this.message)
    .catch(err => console.log(err));
  }

}

私はそれがcorsと何かであるかもしれないと思います。ありがとうございました!

編集:私はちょうどビジュアルスタジオで信号機の実装を再作成し、それが働いた。起動時に間違った設定を選択したと思います。

6
John
connection = new signalR.HubConnectionBuilder()
    .configureLogging(signalR.LogLevel.Debug)
    .withUrl("http://localhost:5000/decisionHub", {
      skipNegotiation: true,
      transport: signalR.HttpTransportType.WebSockets
    })
    .build();
11
Caims

私はよりスリムな問題に直面し、追加して修正しました

skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets

@Caimsが述べたようにクライアント側で。しかし、これは正しい解決策ではないと思い、ハックのように感じますか????。サーバー側にAllowCredentialsを追加する必要があります。とにかく、Azureに来るときは、その修正を中継することはできません。したがって、クライアント側でのみWSSを有効にする必要はありません。

ここに私のConfigureServicesメソッドがあります:

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(o => o.AddPolicy("CorsPolicy", builder => {
        builder
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials()
        .WithOrigins("http://localhost:4200");
    }));

    services.AddSignalR();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

これは私のConfigureメソッドです:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseCors("CorsPolicy");
    app.UseSignalR(routes =>
    {
        routes.MapHub<NotifyHub>("/notify");
    });

    app.UseMvc();
}

最後に、これがクライアント側からの接続方法です。

const connection = new signalR.HubConnectionBuilder()
      .configureLogging(signalR.LogLevel.Debug)
      .withUrl("http://localhost:5000/notify", {
        //skipNegotiation: true,
        //transport: signalR.HttpTransportType.WebSockets
      }).build();

connection.start().then(function () {
    console.log('Connected!');
}).catch(function (err) {
    return console.error(err.toString());
});

connection.on("BroadcastMessage", (type: string, payload: string) => {
    this.msgs.Push({ severity: type, summary: payload });
});
2

プロキシサーバーの設定を確認し、インターネットオプション接続タブを設定してくださいLAN設定->設定を自動的に検出し、プロキシ設定のチェックを外してください。

Azure SignalRサービスAzure Functionに接続しようとすると、Angularアプリケーションで同じ問題に直面していました。

_[FunctionName("Negotiate")]
public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, [SignalRConnectionInfo(HubName = "broadcast")] SignalRConnectionInfo info,
    ILogger log) {
    log.LogInformation("Negotiate trigger function processed a request.");
    return info != null ? (ActionResult) new OkObjectResult(info) : new NotFoundObjectResult("SignalR could not load");
}
_

そして、以下はAngularサービスのinit()関数コードです。

_init() {
    this.getSignalRConnection().subscribe((con: any) => {
        const options = {
            accessTokenFactory: () => con.accessKey
        };

        this.hubConnection = new SignalR.HubConnectionBuilder()
            .withUrl(con.url, options)
            .configureLogging(SignalR.LogLevel.Information)
            .build();

        this.hubConnection.start().catch(error => console.error(error));

        this.hubConnection.on('newData', data => {
            this.mxChipData.next(data);
        });
    });
}
_

私の問題は_con.accessKey_にありました。 SignalRConnectionInfoクラスのプロパティを確認したところ、accessTokenの代わりにaccessKeyを使用する必要があることがわかりました。

_public class SignalRConnectionInfo {
    public SignalRConnectionInfo();

    [JsonProperty("url")]
    public string Url {
        get;
        set;
    }
    [JsonProperty("accessToken")]
    public string AccessToken {
        get;
        set;
    }
}
_

そのため、コードをaccessTokenFactory: () => con.accessTokenに変更した後、すべてが正常に機能しました。

0
Sibeesh Venu

私の場合、これらすべてのものが必要というわけではなく、httpの代わりにhttpsが欠落していました。

const connection = new signalR.HubConnectionBuilder()
  .configureLogging(signalR.LogLevel.Debug)
  .withUrl('https://localhost:44308/message')
  .build();
0
David Castro

私はこれのためにほぼ2日を無駄にし、最終的に把握しました、

このエラーが発生した場合

  • 既存のSignalRサーバープロジェクトを.Net Coreにアップグレードするが、クライアントをアップグレードしない場合
  • .Netコアを使用してSignalRサーバーを作成するが、クライアントに従来の.Netフレームワークを使用する場合

このエラーが発生する理由

  • このエラーは、新しいSignalRでは古いサーバーと新しいクライアント、または新しいサーバーと古いクライアントを使用できないために発生します

  • つまり、.Netコアを使用してSignalRサーバーを作成する場合、.Netコアを使用してクライアントを作成する必要があります

これは私の場合の問題でした。

0
DSA

私は同じ問題を抱えていましたが、signalRchatServerが何もしないという部分のlaunchSettings.json、私と一緒に働いたURLはiisexpressのそれでしたことがわかりました、彼らが言う場所がたくさんあるのでurlは以下のものです。

enter image description here

0
German Gracia