Megosztás a következőn keresztül:


Oktatóanyag: .NET Service Fabric-alkalmazás létrehozása

Ez az oktatóanyag egy sorozat első része. Ebben az oktatóanyagban megtudhatja, hogyan hozhat létre olyan Azure Service Fabric-alkalmazást, amely egy ASP.NET Core Web API előtérrel és egy állapotalapú háttérszolgáltatással rendelkezik az adatok tárolásához. Ha végzett, egy olyan szavazóalkalmazással rendelkezik, amely egy ASP.NET Core webes előtérrel rendelkezik, amely a szavazási eredményeket egy állapotalapú háttérszolgáltatásban menti a fürtben.

Ez az oktatóanyag-sorozat windowsos fejlesztői számítógépet igényel. Ha nem szeretné manuálisan létrehozni a szavazóalkalmazást, akkor letöltheti a forráskódot a kész alkalmazáshoz, és folytathatja a mintául szolgáló szavazóalkalmazás bemutatásával. Az oktatóanyag videós bemutatóját is megtekintheti.

A Service Fabric állapotalapú háttérszolgáltatásához csatlakozó AngularJS+ASP.NET API előtérdiagramja.

Ebben az oktatóanyagban az alábbiakkal fog megismerkedni:

  • ASP.NET Core Web API-szolgáltatás létrehozása állapotalapú megbízható szolgáltatásként
  • ASP.NET Core Web-alkalmazásszolgáltatás létrehozása állapot nélküli webszolgáltatásként
  • Fordított proxy használata az állapotalapú szolgáltatással való kommunikációhoz

Az oktatóanyag-sorozat bemutatja, hogyan:

Előfeltételek

Az oktatóanyag elkezdése előtt:

ASP.NET Web API-szolgáltatás létrehozása megbízható szolgáltatásként

Először hozza létre a szavazóalkalmazás webes előlapját a ASP.NET Core használatával. Az ASP.NET Core egy egyszerűsített, platformfüggetlen webes fejlesztési keretrendszer, amely segítségével modern webes felhasználói felületeket és webes API-kat hozhat létre.

A ASP.NET Core és a Service Fabric integrációjának teljes körű megértéséhez javasoljuk, hogy tekintse át ASP.NET Core-t a Service Fabric Reliable Servicesben. Egyelőre az első lépésekhez elég, ha elvégzi ezt az oktatóanyagot. A ASP.NET Core-ról további információt a ASP.NET Core dokumentációjában talál.

A szolgáltatás létrehozása:

  1. Nyissa meg a Visual Studiót a Futtatás rendszergazdaként lehetőséggel.

  2. Új projekt létrehozásához válassza az Új>projekt fájlja>lehetőséget.

  3. Új projekt létrehozása esetén válassza a Cloud>Service Fabric-alkalmazás lehetőséget. Válassza a Tovább lehetőséget.

    Képernyőkép az Új projekt létrehozása párbeszédpanelről a Visual Studióban.

  4. Válassza az Állapot nélküli ASP.NET Core lehetőséget az új projekttípushoz, nevezze el a szolgáltatás VotingWeb nevét, majd válassza a Létrehozás lehetőséget.

    Képernyőkép egy ASP.NET webszolgáltatás kiválasztásáról az új szolgáltatáspanelen.

  5. A következő panelen ASP.NET Core-projektsablonok láthatók. Ebben az oktatóanyagban válassza a Webalkalmazás (Model-View-Controller) lehetőséget, majd kattintson az OK gombra.

    Képernyőkép a ASP.NET projekttípus kiválasztásáról.

    A Visual Studio létrehoz egy alkalmazást és egy szolgáltatási projektet, majd megjeleníti őket a Visual Studio Megoldáskezelő:

    Képernyőkép az alkalmazás létrehozása utáni Megoldáskezelő az ASP.NET alapvető webes API-szolgáltatás használatával.

A site.js fájl frissítése

Nyissa meg a wwwroot/js/site.js lapot, és nyissa meg a fájlt. Cserélje le a fájl tartalmát a Következő JavaScriptre, amelyet a Kezdőlap nézetek használnak, majd mentse a módosításokat.

var app = angular.module('VotingApp', ['ui.bootstrap']);
app.run(function () { });

app.controller('VotingAppController', ['$rootScope', '$scope', '$http', '$timeout', function ($rootScope, $scope, $http, $timeout) {

    $scope.refresh = function () {
        $http.get('api/Votes?c=' + new Date().getTime())
            .then(function (data, status) {
                $scope.votes = data;
            }, function (data, status) {
                $scope.votes = undefined;
            });
    };

    $scope.remove = function (item) {
        $http.delete('api/Votes/' + item)
            .then(function (data, status) {
                $scope.refresh();
            })
    };

    $scope.add = function (item) {
        var fd = new FormData();
        fd.append('item', item);
        $http.put('api/Votes/' + item, fd, {
            transformRequest: angular.identity,
            headers: { 'Content-Type': undefined }
        })
            .then(function (data, status) {
                $scope.refresh();
                $scope.item = undefined;
            })
    };
}]);

Az Index.cshtml fájl frissítése

Nyissa meg a Views/Home/Index.cshtml fájlt, és nyissa meg a fájlt. Ez a fájl a Kezdőlap vezérlőre jellemző nézetet tartalmaz. Cserélje le a tartalmát a következő kódra, majd mentse a módosításokat.

@{
    ViewData["Title"] = "Service Fabric Voting Sample";
}

<div ng-controller="VotingAppController" ng-init="refresh()">
    <div class="container-fluid">
        <div class="row">
            <div class="col-xs-8 col-xs-offset-2 text-center">
                <h2>Service Fabric Voting Sample</h2>
            </div>
        </div>

        <div class="row">
            <div class="col-xs-8 col-xs-offset-2">
                <form class="col-xs-12 center-block">
                    <div class="col-xs-6 form-group">
                        <input id="txtAdd" type="text" class="form-control" placeholder="Add voting option" ng-model="item"/>
                    </div>
                    <button id="btnAdd" class="btn btn-default" ng-click="add(item)">
                        <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
                        Add
                    </button>
                </form>
            </div>
        </div>

        <hr/>

        <div class="row">
            <div class="col-xs-8 col-xs-offset-2">
                <div class="row">
                    <div class="col-xs-4">
                        Click to vote
                    </div>
                </div>
                <div class="row top-buffer" ng-repeat="vote in votes.data">
                    <div class="col-xs-8">
                        <button class="btn btn-success text-left btn-block" ng-click="add(vote.Key)">
                            <span class="pull-left">
                                {{vote.key}}
                            </span>
                            <span class="badge pull-right">
                                {{vote.value}} Votes
                            </span>
                        </button>
                    </div>
                    <div class="col-xs-4">
                        <button class="btn btn-danger pull-right btn-block" ng-click="remove(vote.Key)">
                            <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
                            Remove
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

A _Layout.cshtml fájl frissítése

Nyissa meg a Views/Shared/_Layout.cshtml fájlt, és nyissa meg a fájlt. Ez a fájl az ASP.NET alkalmazás alapértelmezett elrendezésével rendelkezik. Cserélje le a tartalmát a következő kódra, majd mentse a módosításokat.

<!DOCTYPE html>
<html ng-app="VotingApp" xmlns:ng="https://angularjs.org">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>@ViewData["Title"]</title>

    <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet"/>
    <link href="~/css/site.css" rel="stylesheet"/>

</head>
<body>
<div class="container body-content">
    @RenderBody()
</div>

<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
<script src="~/js/site.js"></script>

@RenderSection("Scripts", required: false)
</body>
</html>

A VotingWeb.cs fájl frissítése

Nyissa meg a VotingWeb.cs fájlt. Ez a fájl létrehozza a ASP.NET Core WebHostot az állapot nélküli szolgáltatásban a WebListener webkiszolgáló használatával.

A fájl elején adja hozzá az using System.Net.Http; irányelvet.

Cserélje le a függvényt CreateServiceInstanceListeners() a következő kódra, majd mentse a módosításokat.

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new ServiceInstanceListener[]
    {
        new ServiceInstanceListener(
            serviceContext =>
                new KestrelCommunicationListener(
                    serviceContext,
                    "ServiceEndpoint",
                    (url, listener) =>
                    {
                        ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                        return new WebHostBuilder()
                            .UseKestrel()
                            .ConfigureServices(
                                services => services
                                    .AddSingleton<HttpClient>(new HttpClient())
                                    .AddSingleton<FabricClient>(new FabricClient())
                                    .AddSingleton<StatelessServiceContext>(serviceContext))
                            .UseContentRoot(Directory.GetCurrentDirectory())
                            .UseStartup<Startup>()
                            .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                            .UseUrls(url)
                            .Build();
                    }))
    };
}

Ezután adja hozzá a következő GetVotingDataServiceName metódust CreateServiceInstanceListeners(), majd mentse a módosításokat. A GetVotingDataServiceName lekérdezéskor visszaadja a szolgáltatás nevét.

internal static Uri GetVotingDataServiceName(ServiceContext context)
{
    return new Uri($"{context.CodePackageActivationContext.ApplicationName}/VotingData");
}

A VotesController.cs fájl hozzáadása

Adjon hozzá egy vezérlőt a szavazati műveletek definiálásához. Kattintson a jobb gombbal a Vezérlők mappára, majd válassza az Új elem>hozzáadása>Visual C#>ASP.NET Core>Class lehetőséget. Nevezze el a fájlt VotesController.cs, majd válassza a Hozzáadás lehetőséget.

Cserélje le a VotesController.cs fájl tartalmát a következő kódra, majd mentse a módosításokat. A későbbiekben, a VotesController.cs fájl frissítése során ez a fájl úgy módosul, hogy a háttérszolgáltatásból a szavazás adatait olvasni és írni is tudja. Egyelőre a vezérlő statikus sztringadatokat ad vissza a nézetben.

namespace VotingWeb.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Fabric;
    using System.Fabric.Query;
    using System.Linq;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;

    [Produces("application/json")]
    [Route("api/Votes")]
    public class VotesController : Controller
    {
        private readonly HttpClient httpClient;

        public VotesController(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        // GET: api/Votes
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            List<KeyValuePair<string, int>> votes= new List<KeyValuePair<string, int>>();
            votes.Add(new KeyValuePair<string, int>("Pizza", 3));
            votes.Add(new KeyValuePair<string, int>("Ice cream", 4));

            return Json(votes);
        }
     }
}

A figyelőport konfigurálása

A VotingWeb kezelőfelületi szolgáltatás létrehozásakor a Visual Studio véletlenszerűen kiválaszt egy portot, amelyen a szolgáltatás a figyelést végzi. A VotingWeb szolgáltatás az alkalmazás előtereként működik, és elfogadja a külső forgalmat. Ebben a szakaszban ezt a szolgáltatást egy rögzített és jól ismert porthoz köti. A szolgáltatásjegyzék deklarálja a szolgáltatásvégpontokat.

A Megoldáskezelőben nyissa meg a következőt: VotingWeb/PackageRoot/ServiceManifest.xml. Resources A szakaszban keresse meg az Endpoint elemet, majd módosítsa az értéket a Port következőre8080: .

Az alkalmazás helyi üzembe helyezéséhez és futtatásához az alkalmazásfigyelő-portnak a számítógépen megnyitva és elérhető állapotban kell lennie.

<Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to 
           listen. Please note that if your service is partitioned, this port is shared with 
           replicas of different partitions that are placed in your code. -->
      <Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8080" />
    </Endpoints>
  </Resources>

Ezután frissítse a Application URL tulajdonság értékét a Voting projektben, hogy egy webböngésző a megfelelő portra nyíljon az alkalmazás hibakeresésekor. A Megoldáskezelő válassza ki a Szavazó projektet, majd frissítse a tulajdonságot a Application URL következőre8080: .

A szavazóalkalmazás helyi üzembe helyezése és futtatása

Most már futtathatja a szavazóalkalmazást a hibakereséshez. A Visual Studióban az F5 lehetőséget választva telepítse az alkalmazást a helyi Service Fabric-fürtre hibakeresési módban. Az alkalmazás meghiúsul, ha korábban nem nyitotta meg a Visual Studiót a Futtatás rendszergazdaként lehetőséggel.

Feljegyzés

Amikor először futtatja és telepíti az alkalmazást helyileg, a Visual Studio létrehoz egy helyi Service Fabric-fürtöt a hibakereséshez. A fürt létrehozásának folyamata eltarthat egy ideig. A fürtlétrehozás állapota megjelenik a Visual Studio Kimenet ablakában.

Miután telepítette a szavazóalkalmazást a helyi Service Fabric-fürtön, a webalkalmazás automatikusan megnyílik egy böngészőlapon. A következő példához hasonlóan néz ki:

Képernyőkép az alkalmazás előtérről egy böngészőben.

Az alkalmazás hibakeresésének leállításához lépjen vissza a Visual Studióba, és válassza a Shift+F5 billentyűkombinációt.

Állapotalapú háttérszolgáltatás hozzáadása az alkalmazáshoz

Most, hogy egy ASP.NET Web API-szolgáltatás fut az alkalmazásban, adjon hozzá egy állapotalapú megbízható szolgáltatást, amely bizonyos adatokat tárol az alkalmazásban.

A Service Fabric használatával megbízható gyűjtemények használatával konzisztensen és megbízhatóan tárolhatja az adatokat közvetlenül a szolgáltatásban. A megbízható gyűjtemények olyan magas rendelkezésre állású és megbízható gyűjteményosztályok, amelyek mindenki számára ismerősek, akik C# gyűjteményeket használnak.

Olyan szolgáltatás létrehozása, amely számlálóértéket tárol egy megbízható gyűjteményben:

  1. A Megoldáskezelő kattintson a jobb gombbal a Szolgáltatások elemre a Szavazóalkalmazás projektben, és válassza az Új Service Fabric-szolgáltatás hozzáadása>lehetőséget.

  2. Az Új Service Fabric szolgáltatás párbeszédpanelen válassza az Állapotalapú ASP.NET Core lehetőséget, nevezze el a szolgáltatás VotingData nevét, majd kattintson az OK gombra.

    A szolgáltatási projekt létrehozása után két szolgáltatással rendelkezik az alkalmazásban. Ahogy folytatja az alkalmazás összeállítását, ugyanúgy adhat hozzá további szolgáltatásokat is. Minden szolgáltatás külön verziószámozott és frissíthető.

  3. A következő panelen ASP.NET Core-projektsablonok láthatók. Ebben az oktatóanyagban válassza az API-t.

    A Visual Studio létrehozza a VotingData szolgáltatásprojektet, és megjeleníti azt a Megoldáskezelő:

    Képernyőkép a VotingData szolgáltatás projektről a Megoldáskezelő.

A VoteDataController.cs fájl hozzáadása

A VotingData projektben kattintson a jobb gombbal a Vezérlők mappára, majd válassza az Új elemosztály> hozzáadása>lehetőséget. Nevezze el a fájlt VoteDataController.cs, és válassza a Hozzáadás lehetőséget. Cserélje le a fájl tartalmát a következő kódra, majd mentse a módosításokat.

namespace VotingData.Controllers
{
    using System.Collections.Generic;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.ServiceFabric.Data;
    using Microsoft.ServiceFabric.Data.Collections;

    [Route("api/[controller]")]
    public class VoteDataController : Controller
    {
        private readonly IReliableStateManager stateManager;

        public VoteDataController(IReliableStateManager stateManager)
        {
            this.stateManager = stateManager;
        }

        // GET api/VoteData
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            CancellationToken ct = new CancellationToken();

            IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                Microsoft.ServiceFabric.Data.IAsyncEnumerable<KeyValuePair<string, int>> list = await votesDictionary.CreateEnumerableAsync(tx);

                Microsoft.ServiceFabric.Data.IAsyncEnumerator<KeyValuePair<string, int>> enumerator = list.GetAsyncEnumerator();

                List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();

                while (await enumerator.MoveNextAsync(ct))
                {
                    result.Add(enumerator.Current);
                }

                return this.Json(result);
            }
        }

        // PUT api/VoteData/name
        [HttpPut("{name}")]
        public async Task<IActionResult> Put(string name)
        {
            IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                await votesDictionary.AddOrUpdateAsync(tx, name, 1, (key, oldvalue) => oldvalue + 1);
                await tx.CommitAsync();
            }

            return new OkResult();
        }

        // DELETE api/VoteData/name
        [HttpDelete("{name}")]
        public async Task<IActionResult> Delete(string name)
        {
            IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");

            using (ITransaction tx = this.stateManager.CreateTransaction())
            {
                if (await votesDictionary.ContainsKeyAsync(tx, name))
                {
                    await votesDictionary.TryRemoveAsync(tx, name);
                    await tx.CommitAsync();
                    return new OkResult();
                }
                else
                {
                    return new NotFoundResult();
                }
            }
        }
    }
}

A szolgáltatások összekapcsolása

Ebben a szakaszban két szolgáltatást csatlakoztat. Az előtér-webalkalmazást lekérheti a háttérszolgáltatásból, majd beállíthatja az adatokat az alkalmazásban.

A Service Fabric teljes rugalmasságot biztosít a megbízható szolgáltatásokkal való kommunikációhoz. Előfordulhat, hogy egyetlen alkalmazáson belül TCP/IP-címen, HTTP REST API-n vagy WebSocket protokollon keresztül elérhető szolgáltatások érhetők el. Az elérhető lehetőségek és azok kompromisszumainak hátterét a Szolgáltatásokkal való kommunikáció című témakörben tekinthetik meg.

Ez az oktatóanyag ASP.NET Core Web API-t és a Service Fabric fordított proxyt használ, hogy a VotingWeb előtér-webszolgáltatás kommunikálni tudjon a háttérrendszer VotingData szolgáltatásával. A fordított proxy alapértelmezés szerint az 19081-s port használatára van konfigurálva. A fordított proxyport a fürtöt beállító Azure Resource Manager-sablonban van beállítva. A használt port megkereséséhez keresse meg az erőforrás fürtsablonjában:Microsoft.ServiceFabric/clusters

"nodeTypes": [
          {
            ...
            "httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
            "isPrimary": true,
            "vmInstanceCount": "[parameters('nt0InstanceCount')]",
            "reverseProxyEndpointPort": "[parameters('SFReverseProxyPort')]"
          }
        ],

A helyi fejlesztési fürtben használt fordított proxyport megkereséséhez tekintse meg a HttpApplicationGatewayEndpoint helyi Service Fabric-fürt jegyzékében található elemet:

  1. A Service Fabric Explorer eszköz megnyitásához nyisson meg egy böngészőt, és nyissa meg a következőt http://localhost:19080: .
  2. Válassza a Fürtjegyzék>lehetőséget.
  3. Jegyezze fel az HttpApplicationGatewayEndpoint elemportot. Alapértelmezés szerint a port 19081. Ha nem 19081, módosítsa a portot a GetProxyAddressVotesController.cs kód metódusában a következő szakaszban leírtak szerint.

A VotesController.cs fájl frissítése

Nyissa meg a Controllers/VotesController.cs fájlt a VotingWeb projektben. Cserélje le az VotesController osztálydefiníció tartalmát a következő kódra, majd mentse a módosításokat. Ha a perverz lépésben felderített fordított proxyport nem 19081, módosítsa a GetProxyAddress metódus portját a felderített portra 19081 .

public class VotesController : Controller
{
    private readonly HttpClient httpClient;
    private readonly FabricClient fabricClient;
    private readonly StatelessServiceContext serviceContext;

    public VotesController(HttpClient httpClient, StatelessServiceContext context, FabricClient fabricClient)
    {
        this.fabricClient = fabricClient;
        this.httpClient = httpClient;
        this.serviceContext = context;
    }

    // GET: api/Votes
    [HttpGet("")]
    public async Task<IActionResult> Get()
    {
        Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
        Uri proxyAddress = this.GetProxyAddress(serviceName);

        ServicePartitionList partitions = await this.fabricClient.QueryManager.GetPartitionListAsync(serviceName);

        List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();

        foreach (Partition partition in partitions)
        {
            string proxyUrl =
                $"{proxyAddress}/api/VoteData?PartitionKey={((Int64RangePartitionInformation) partition.PartitionInformation).LowKey}&PartitionKind=Int64Range";

            using (HttpResponseMessage response = await this.httpClient.GetAsync(proxyUrl))
            {
                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    continue;
                }

                result.AddRange(JsonConvert.DeserializeObject<List<KeyValuePair<string, int>>>(await response.Content.ReadAsStringAsync()));
            }
        }

        return this.Json(result);
    }

    // PUT: api/Votes/name
    [HttpPut("{name}")]
    public async Task<IActionResult> Put(string name)
    {
        Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
        Uri proxyAddress = this.GetProxyAddress(serviceName);
        long partitionKey = this.GetPartitionKey(name);
        string proxyUrl = $"{proxyAddress}/api/VoteData/{name}?PartitionKey={partitionKey}&PartitionKind=Int64Range";

        StringContent putContent = new StringContent($"{{ 'name' : '{name}' }}", Encoding.UTF8, "application/json");
        putContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        using (HttpResponseMessage response = await this.httpClient.PutAsync(proxyUrl, putContent))
        {
            return new ContentResult()
            {
                StatusCode = (int) response.StatusCode,
                Content = await response.Content.ReadAsStringAsync()
            };
        }
    }

    // DELETE: api/Votes/name
    [HttpDelete("{name}")]
    public async Task<IActionResult> Delete(string name)
    {
        Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
        Uri proxyAddress = this.GetProxyAddress(serviceName);
        long partitionKey = this.GetPartitionKey(name);
        string proxyUrl = $"{proxyAddress}/api/VoteData/{name}?PartitionKey={partitionKey}&PartitionKind=Int64Range";

        using (HttpResponseMessage response = await this.httpClient.DeleteAsync(proxyUrl))
        {
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                return this.StatusCode((int) response.StatusCode);
            }
        }

        return new OkResult();
    }


    /// <summary>
    /// Constructs a reverse proxy URL for a given service.
    /// Example: http://localhost:19081/VotingApplication/VotingData/
    /// </summary>
    /// <param name="serviceName"></param>
    /// <returns></returns>
    private Uri GetProxyAddress(Uri serviceName)
    {
        return new Uri($"http://localhost:19081{serviceName.AbsolutePath}");
    }

    /// <summary>
    /// Creates a partition key from the given name.
    /// Uses the zero-based numeric position in the alphabet of the first letter of the name (0-25).
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    private long GetPartitionKey(string name)
    {
        return Char.ToUpper(name.First()) - 'A';
    }
}

A mintául szolgáló szavazóalkalmazás bemutatása

A szavazóalkalmazás két szolgáltatásból áll:

  • Webes előtérbeli szolgáltatás (VotingWeb): Egy ASP.NET Core webes előtér-szolgáltatás, amely a weblapot szolgálja ki, és webes API-kat tesz elérhetővé a háttérszolgáltatással való kommunikációhoz.
  • Háttérszolgáltatás (VotingData): Egy ASP.NET Core webszolgáltatás, amely egy API-t tesz elérhetővé a szavazási eredmények tárolásához, egy megbízható, lemezen tárolt szótárban.

Az alkalmazásszolgáltatásokat ábrázoló diagram.

Amikor az alkalmazásban szavaz, a következő események következnek be:

  1. Egy JavaScript-fájl HTTP PUT-kérésként elküldi a szavazási kérelmet a webes API-nak a webes előtér-szolgáltatásban.

  2. A webes kezelőfelületi szolgáltatás egy proxy segítségével megkeresi és továbbítja a HTTP PUT kérelmet a háttérszolgáltatásnak.

  3. A háttérszolgáltatás felveszi a bejövő kérést, és megbízható szótárban tárolja a frissített eredményt. A rendszer replikálja a szótárt a fürt több csomópontjára, és a lemezen marad. Az alkalmazás összes adata a fürtön tárolódik, így nincs szükség adatbázisra.

Hibakeresés a Visual Studióban

Egy alkalmazás Visual Studióban történő hibakeresésekor egy helyi Service Fabric-fejlesztési fürtöt használ. A hibakeresési élményt a forgatókönyvéhez igazíthatja.

Ebben az alkalmazásban egy megbízható szótár használatával tárolhatja az adatokat a háttérszolgáltatásban. A Visual Studio alapértelmezés szerint eltávolítja az alkalmazást, amikor leállítja a hibakeresőt. Az alkalmazás eltávolításával a háttérszolgáltatásban tárolt adatok is el lesznek távolítva. Ha szeretné megtartani az adatokat a hibakeresési munkamenetek között, akkor módosítania kell az Application Debug Mode (Alkalmazás hibakeresési módja) tulajdonságot a Voting (Szavazás) projektben a Visual Studióban.

A kódban megjelenő műveletek megtekintéséhez hajtsa végre a következő lépéseket:

  1. Nyissa meg a VotingWeb\VotesController.cs fájlt, és állítson be egy töréspontot a webes API Put metódusában (72. sor).

  2. Nyissa meg a VotingData\VoteDataController.cs fájlt, és állítson be egy töréspontot a webes API Put metódusában (54. sor).

  3. Az F5 lehetőséget választva indítsa el az alkalmazást hibakeresési módban.

  4. Lépjen vissza a böngészőbe, és válasszon ki egy szavazási lehetőséget, vagy adjon hozzá egy új választógombot. A webes előtérbeli API-vezérlő első töréspontját találta el.

    A böngészőBen található JavaScript kérést küld a webes API-vezérlőnek az előtérbeli szolgáltatásban:

    Képernyőkép egy szavazási előtér-szolgáltatás hozzáadásáról.

    1. Először hozza létre a háttérszolgáltatás fordított proxyjának URL-címét. (1)
    2. Ezután küldje el a HTTP PUT kérést a fordított proxynak. (2)
    3. Végül adja vissza a háttérszolgáltatás válaszát az ügyfélnek. (3)
  5. A folytatáshoz válassza az F5 lehetőséget.

    Most a háttérszolgáltatás töréspontján van:

    Képernyőkép a szavazás háttérszolgáltatáshoz való hozzáadásáról.

    1. A metódus első sorában egy megbízható, úgynevezett countsszótár lekérésére vagy hozzáadására használhatóstateManager. (1)
    2. A megbízható szótárban értékekkel rendelkező összes interakcióhoz tranzakcióra van szükség. Ez az using utasítás létrehozza ezt a tranzakciót. (2)
    3. A tranzakcióban frissítse a szavazási lehetőséghez tartozó kulcs értékét, és véglegesítse a műveletet. Amikor a commit metódus visszatér, az adatok frissülnek a szótárban. Ezután replikálja a fürt más csomópontjaira. Az adatok most már biztonságosan tárolódnak a fürtben, és a háttérszolgáltatás feladatátvételt végezhet más csomópontokon, és továbbra is rendelkezésre állnak az adatok. (3)
  6. A folytatáshoz válassza az F5 lehetőséget.

A hibakeresési munkamenet leállításához válassza a Shift+F5 billentyűkombinációt.

Következő lépés

Folytassa a következő oktatóanyaggal: