React + ASPNET Core + Prerendering: была сделана попытка получить доступ к сокету способом, запрещенным его правами доступа - PullRequest
0 голосов
/ 10 октября 2018

У меня есть приложение .NET Core + React, использующее aspnet-prerendering.Я создал приложение, используя dotnet new reactredux .Я опубликовал это в Azure и направил в это приложение с помощью AWS CloudFront.

Приложение работало во всех средах (локально, CI, предварительная установка ...), но когда я развернул его в производство, оно работало в течение нескольких дней, а затем я начал получать множество ошибок An attempt was made to access a socket in a way forbidden by its access permissions.Это происходит, когда POST установлен на 127.0.0.1:<randomPort>.Я не делаю это POST в моем коде, и мне сказали, что это связано с тем, как отреагирует реакция.Эти ошибки обычно начинаются через 1-2 дня после развертывания.Поэтому при первом развертывании все выглядит хорошо, но затем, когда появляются ошибки, они продолжаются до тех пор, пока я повторно не разверну или не перезапущу приложение в Azure.


То, что я пробовал:

  • Перезапуск приложения на некоторое время устраняет проблему.
  • Я слышал, что это вызвано реакциейгорячая перезагрузка, поэтому я обязательно добавил в Azure набор приложений: ASPNETCORE_ENVIRONMENT=Production.Это не решило проблему.
  • Я попытался полностью закомментировать часть горячей перезагрузки файла Startup.cs, чтобы проверить эту гипотезу ... но ошибки все равно возобновились через 2 дня после развертывания этого кода.

Пример списка портов, которые не срабатывают, с успехом (на первый взгляд случайные ...?):

success count_  data
FALSE   3493    http://127.0.0.1:53571
FALSE   1353    http://127.0.0.1:49988
FALSE   535     http://127.0.0.1:55453
FALSE   484     http://127.0.0.1:53144
FALSE   13      http://127.0.0.1:52428
FALSE   7       http://127.0.0.1:49583
TRUE    11247   http://127.0.0.1:56790
TRUE    10960   http://127.0.0.1:55806
TRUE    10920   http://127.0.0.1:55227
TRUE    9300    http://127.0.0.1:55453
TRUE    8472    http://127.0.0.1:51734
TRUE    5602    http://127.0.0.1:53571
TRUE    5429    http://127.0.0.1:56860

Фрагменты кода:

Запуск:

public void ConfigureServices(IServiceCollection services)
{    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    // In production, the React files will be served from this directory
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/build";
    });
    …
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
        {
            HotModuleReplacement = true,
            ReactHotModuleReplacement = true,
            // This configuration suppresses the warnings that the server code doesn't match the client code, which happens on reload.
            HotModuleReplacementClientOptions = new Dictionary<string, string>()
            {
                { "warn", "false" }
            }
        });
    }
    else
    {
    app.UseExceptionHandler("/Error");
    app.UseHsts();
    }

    //app.UseHttpsRedirection();
    app.UseStaticFiles();
    …
}

Index.cshtml

@using Microsoft.Extensions.Configuration
@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnv
@inject IConfiguration Configuration

<script>
    window.data = @Html.Raw(Json.Serialize(@Model));
</script>

<div id="col-app"
     asp-prerender-module="./wwwroot/cost-of-living-calculator/dist/main-server"
     asp-prerender-webpack-config="webpack.config.server.js"
     asp-prerender-data="@Model">Loading...</div>

@if (hostingEnv.EnvironmentName == "Production")
{
    <script src="/cost-of-living-calculator/dist/main.min.js" asp-append-version="true"></script>
}
else
{
    <script src="/cost-of-living-calculator/dist/main.js" asp-append-version="true"></script>
}

Package.json

...
"aspnet-prerendering": "3.0.1",
"aspnet-webpack": "3.0.0",
"aspnet-webpack-react": "3.0.0",
...

ПРИМЕЧАНИЕ. У меня есть загрузочный сервер изагрузочный клиент, а также конфигурацию веб-пакета сервера и конфигурацию веб-пакета клиента.Это связано с различными потребностями в компиляции сервера / клиента.

Boot-server.js

import React from 'react';
import { createServerRenderer } from 'aspnet-prerendering';
import { renderToString } from 'react-dom/server';
import App from './App';

export default createServerRenderer(
  params =>
    new Promise((resolve, reject) => {
      const data = params.data;
      const result = renderToString(React.createElement(App, data));

      resolve({ html: result });
    })
);

Boot-client.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

const element = document.getElementById('col-app');
ReactDOM.render(<App {...window.data} />, element);

// This is required to trigger the hot reloading functionality
if (module.hot) {
  module.hot.accept('./App', () => {
    const NewApp = require('./App').default;
    ReactDOM.render(<NewApp {...window.data} />, element);
  });
}

Webpack.config.js

var path = require('path');
var webpack = require('webpack'); 
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development';

module.exports = () => {
  return {
    devtool: 'inline-source-map',
    entry: {
    'main': ['babel-polyfill', './ClientApp/boot-client.js', './ClientApp/index.scss'],
},
optimization: {
  minimizer: [
    new UglifyJsPlugin({
      cache: true,
      parallel: true,
      sourceMap: true // set to true if you want JS source maps
    }),
    new OptimizeCSSAssetsPlugin({})
  ]
},
output: {
  path: path.join(__dirname, './wwwroot/cost-of-living-calculator/dist'),
  publicPath: '/cost-of-living-calculator/dist/',
  filename: isDevelopment ? "[name].js" : "[name].min.js"
},
plugins: [
  new MiniCssExtractPlugin({
    // Options similar to the same options in webpackOptions.output
    // both options are optional
    filename: "[name].css",
    chunkFilename: "[id].css"
  })
],
module: {
  rules: [
    {
      // JavaScript files, which will be transpiled
      // based on .babelrc
      test: /\.(js|jsx)$/,
      exclude: [/node_modules/],
      loader: ['babel-loader', 'source-map-loader']
    },
    {
      test: /\.s?css$/,
      use: isDevelopment ? [
        'style-loader',
        'css-loader',
        'sass-loader',
      ] : [
        MiniCssExtractPlugin.loader,
        'css-loader',
        'sass-loader'
      ]
    }
  ]
},
mode: isDevelopment ? 'development' : 'production'
  }
};

Webpack.config.server.js

var path = require('path');
const isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development';

module.exports = () => {
  return {
    devtool: 'inline-source-map',
    entry: {
      'main-server': ['babel-polyfill', './ClientApp/boot-server.js']
    },
    output: {
      path: path.join(__dirname, './wwwroot/cost-of-living-calculator/dist'),
      publicPath: '/cost-of-living-calculator/dist/',
      filename: "[name].js",
      // commonjs is required for server-side compilation
      libraryTarget: 'commonjs'
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: [/node_modules/],
          loader: ['babel-loader', 'source-map-loader']
        }
      ]
    },
    target: 'node',
    mode: isDevelopment ? 'development' : 'production'
  }
};

Мой вопрос: почему это происходит?Как мне это предотвратить?

1 Ответ

0 голосов
/ 10 июня 2019

Похоже, вам нужно предоставить разрешения для вашего сервиса node.js, который используется для предварительной визуализации.Также проверьте ваши запросы SSR

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...