React Native app won't complete negotiation wi

2020-07-23 05:36发布

I'm trying to integrate the SignalR Core JS client on React Native but can't quite seem to get it to work with a ASP.NET Core server with SignalR. I've heard that other people have been able to make it work despite the lack of a designated React Native client.

I keep getting the following error: "Error: Failed to complete negotiation with the server: Error". Could someone help me?

Here's what the React Native app looks like:

App.js

import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View, TouchableHighlight, TextInput, Alert } from 'react-native';

import * as signalR from '@aspnet/signalr';

export default class App extends Component {

  componentDidMount() {
    let connection = new signalR.HubConnectionBuilder()
      .withUrl("http://192.168.0.89:5000/app")
      .configureLogging(signalR.LogLevel.Information)
      .build();

    connection.on("ReceiveMessage", (user, message) => {
      const msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
      const encodedMsg = user + " says " + msg;
      log(encodedMsg);
    });

    connection.start().catch(err => this.logError(err));
  }

  render() {
    return (
      <View style={styles.container}>

      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

Package.json

{
  "name": "TakMobile",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "@aspnet/signalr": "^1.0.4",
    "react": "16.6.0-alpha.8af6728",
    "react-native": "0.57.4",
    "react-native-callkit": "^1.3.4",
    "react-native-voip-push-notification": "^1.1.2",
    "react-native-webrtc": "^1.67.1",
    "socket.io-client": "^2.1.1"
  },
  "devDependencies": {
    "babel-jest": "23.6.0",
    "jest": "23.6.0",
    "metro-react-native-babel-preset": "0.49.0",
    "react-test-renderer": "16.6.0-alpha.8af6728"
  },
  "jest": {
    "preset": "react-native"
  }
}

Here's what the server looks like:

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace demo1
{
    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.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.UseFileServer();
            app.UseSignalR(routes =>
            {
                routes.MapHub<ApplicationHub>("/app");
            });
        }
    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace demo1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

Demo1.cs project file

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

launchSettings.json

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://192.168.0.89:5002",
      "sslPort": 44397
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "demo1": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://192.168.0.89:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

ApplicationHub.cs

using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace demo1 {
    public class ApplicationHub : Hub {
        public Task Send(string message) {
            return Clients.All.SendAsync("Send", message);
        }
    }
}

1条回答
做个烂人
2楼-- · 2020-07-23 06:08

Turns out React Native had an issue connecting perhaps because of the https protocol. Furthermore, I also explicitly added 'Microsoft.AspNetCore.SignalR' version 1.0.4 to match the version on React Native even though it should be included in 'Microsoft.AspNetCore.App'.

So, here's the updated code that works on both React and React Native:

App.js

import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View, TouchableHighlight, TextInput, Alert } from 'react-native';

import * as signalR from '@aspnet/signalr';

export default class App extends Component {

  componentDidMount() {
    const hubUrl = 'http://192.168.0.89:5000/app';

const connectionHub = new signalR.HubConnectionBuilder()
  .withUrl(hubUrl)
  .configureLogging(signalR.LogLevel.Information)
  .build();

connectionHub.on('ReceiveMessage', this.messageReceived);
connectionHub.start()
  .catch(err => this.logError(err));
  }

  render() {
    return (
      <View style={styles.container}>

      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

Here's what the server looks like:

Startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace demo1
{
    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.AddSignalR();
            services.AddCors();
            services.AddMvc();
        }

        // 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(cors => {
                cors.AllowAnyHeader();
                cors.AllowAnyOrigin();
                cors.AllowAnyMethod();
                cors.AllowCredentials();
            });
            app.UseSignalR(routes =>
            {
                routes.MapHub<ApplicationHub>("/app");
            });


            app.UseHttpsRedirection();
            app.UseWebSockets();
            app.UseMvc();

        }
    }
}

Demo1.cs project file

   <Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.0.4" />
  </ItemGroup>

</Project>

launchSettings.json

 {
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://*:5002",
      "sslPort": 44397
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "demo1": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://*:5000;https://*:5001",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}
查看更多
登录 后发表回答