Results site in .NET Core
This commit is contained in:
parent
879e5bc477
commit
985af62bb1
42
docker-compose-windows.yml
Normal file
42
docker-compose-windows.yml
Normal file
@ -0,0 +1,42 @@
|
||||
version: "3.2"
|
||||
|
||||
services:
|
||||
vote:
|
||||
build:
|
||||
context: ./vote/dotnet
|
||||
ports:
|
||||
- "5000:80"
|
||||
depends_on:
|
||||
- message-queue
|
||||
|
||||
result:
|
||||
build:
|
||||
context: ./result/dotnet
|
||||
ports:
|
||||
- "5001:80"
|
||||
environment:
|
||||
- "Data:ConnectionString=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
worker:
|
||||
build:
|
||||
context: ./worker/dotnet
|
||||
environment:
|
||||
- "Data:ConnectionString=Server=db;Port=4000;Database=votes;User=root;SslMode=None"
|
||||
depends_on:
|
||||
- message-queue
|
||||
- db
|
||||
|
||||
message-queue:
|
||||
image: nats:nanoserver
|
||||
|
||||
db:
|
||||
image: dockersamples/tidb:nanoserver
|
||||
ports:
|
||||
- "3306:4000"
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: nat
|
16
result/dotnet/Dockerfile
Normal file
16
result/dotnet/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
||||
FROM microsoft/dotnet:2.1-sdk as builder
|
||||
|
||||
WORKDIR /Result
|
||||
COPY Result/Result.csproj .
|
||||
RUN dotnet restore
|
||||
|
||||
COPY /Result .
|
||||
RUN dotnet publish -c Release -o /out Result.csproj
|
||||
|
||||
# app image
|
||||
FROM microsoft/dotnet:2.1-aspnetcore-runtime
|
||||
|
||||
WORKDIR /app
|
||||
ENTRYPOINT ["dotnet", "Result.dll"]
|
||||
|
||||
COPY --from=builder /out .
|
@ -1,14 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Result.Models;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
||||
namespace Result.Hubs
|
||||
{
|
||||
public class ResultsHub : Hub
|
||||
{
|
||||
public async Task UpdateResults(ResultsModel results)
|
||||
{
|
||||
await Clients.All.SendAsync("UpdateResults", results);
|
||||
}
|
||||
//no public methods, only used for push from PublishRTesultsTimer
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,5 @@
|
||||
public int OptionB { get; set; }
|
||||
|
||||
public int VoteCount { get; set; }
|
||||
|
||||
public double OptionAPercent { get; set; }
|
||||
|
||||
public double OptionBPercent { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
@page
|
||||
@model Result.Pages.IndexModel
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Cats vs Dogs -- Result</title>
|
||||
<title>@Model.OptionA vs @Model.OptionB -- Result</title>
|
||||
<base href="/index.html">
|
||||
<meta name="viewport" content="width=device-width, initial-scale = 1.0">
|
||||
<meta name="keywords" content="docker-compose, docker, stack">
|
||||
<meta name="author" content="Docker">
|
||||
<link rel='stylesheet' href='/stylesheets/style.css' />
|
||||
<link rel='stylesheet' href='~/css/site.css' />
|
||||
</head>
|
||||
<body>
|
||||
<div id="background-stats">
|
||||
@ -22,22 +24,20 @@
|
||||
<div id="content-container">
|
||||
<div id="content-container-center">
|
||||
<div id="choice">
|
||||
<div class="choice cats">
|
||||
<div class="label">Cats</div>
|
||||
<div class="choice resulta">
|
||||
<div class="label">@Model.OptionA</div>
|
||||
<div class="stat" id="optionA"></div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="choice dogs">
|
||||
<div class="label">Dogs</div>
|
||||
<div class="choice resultb">
|
||||
<div class="label">@Model.OptionB</div>
|
||||
<div class="stat" id="optionB"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="result">
|
||||
<span ng-if="total == 0">No votes yet</span>
|
||||
<span ng-if="total == 1">{{total}} vote</span>
|
||||
<span ng-if="total >= 2">{{total}} votes</span>
|
||||
<span id="totalVotes">No votes yet</span>
|
||||
</div>
|
||||
<script src="~/lib/signalr/dist/browser/signalr.js"></script>
|
||||
<script src="~/js/results.js"></script>
|
||||
|
@ -4,14 +4,30 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Result.Pages
|
||||
{
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
private string _optionA;
|
||||
private string _optionB;
|
||||
protected readonly IConfiguration _configuration;
|
||||
|
||||
public string OptionA { get; private set; }
|
||||
public string OptionB { get; private set; }
|
||||
|
||||
public IndexModel(IConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
_optionA = _configuration.GetValue<string>("Voting:OptionA");
|
||||
_optionB = _configuration.GetValue<string>("Voting:OptionB");
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
|
||||
OptionA = _optionA;
|
||||
OptionB = _optionB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:56785",
|
||||
"sslPort": 44369
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
@ -18,10 +18,10 @@
|
||||
"Result": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +1,10 @@
|
||||
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.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Result.Hubs;
|
||||
using Result.Timers;
|
||||
|
||||
namespace Result
|
||||
{
|
||||
@ -26,6 +21,7 @@ namespace Result
|
||||
{
|
||||
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||
services.AddSignalR();
|
||||
services.AddSingleton<PublishResultsTimer>();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
@ -45,6 +41,9 @@ namespace Result
|
||||
routes.MapHub<ResultsHub>("/resultsHub");
|
||||
});
|
||||
app.UseMvc();
|
||||
|
||||
var timer = app.ApplicationServices.GetService<PublishResultsTimer>();
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
47
result/dotnet/Result/Timers/PublishResultsTimer.cs
Normal file
47
result/dotnet/Result/Timers/PublishResultsTimer.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Timers;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Result.Hubs;
|
||||
using Result.Models;
|
||||
|
||||
namespace Result.Timers
|
||||
{
|
||||
public class PublishResultsTimer
|
||||
{
|
||||
private readonly IHubContext<ResultsHub> _hubContext;
|
||||
private readonly Timer _timer;
|
||||
//TODO- temp
|
||||
private static Random _Random = new Random();
|
||||
|
||||
public PublishResultsTimer(IHubContext<ResultsHub> hubContext, IConfiguration configuration)
|
||||
{
|
||||
_hubContext = hubContext;
|
||||
var publishMilliseconds = configuration.GetValue<int>("ResultsTimer:PublishMilliseconds");
|
||||
_timer = new Timer(publishMilliseconds)
|
||||
{
|
||||
Enabled = false
|
||||
};
|
||||
_timer.Elapsed += PublishResults;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (!_timer.Enabled)
|
||||
{
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void PublishResults(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var model = new ResultsModel
|
||||
{
|
||||
OptionA = _Random.Next(0, 100),
|
||||
OptionB = _Random.Next(0, 100)
|
||||
};
|
||||
model.VoteCount = model.OptionA + model.OptionB;
|
||||
_hubContext.Clients.All.SendAsync("UpdateResults", model);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,11 @@
|
||||
{
|
||||
"Voting": {
|
||||
"OptionA": "Cats",
|
||||
"OptionB": "Dogs"
|
||||
},
|
||||
"ResultsTimer": {
|
||||
"PublishMilliseconds": 1500
|
||||
},
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
|
@ -95,12 +95,12 @@ body {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#choice .choice.dogs {
|
||||
#choice .choice.resultb {
|
||||
color: #00cbca;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#choice .choice.cats {
|
||||
#choice .choice.resulta {
|
||||
color: #2196f3;
|
||||
float: left;
|
||||
}
|
||||
|
@ -3,14 +3,23 @@
|
||||
var connection = new signalR.HubConnectionBuilder().withUrl("/resultsHub").build();
|
||||
|
||||
connection.on("UpdateResults", function (results) {
|
||||
data = JSON.parse(json);
|
||||
document.body.style.opacity=1;
|
||||
|
||||
var a = parseInt(data.optionA || 0);
|
||||
var b = parseInt(data.optionB || 0);
|
||||
var a = parseInt(results.optionA || 0);
|
||||
var b = parseInt(results.optionB || 0);
|
||||
var percentages = getPercentages(a, b);
|
||||
|
||||
document.getElementById("optionA").innerText = percentages.a + "%";
|
||||
document.getElementById("optionB").innerText = percentages.b + "%";
|
||||
if (results.voteCount > 0) {
|
||||
var totalVotes = results.voteCount + (results.voteCount > 1 ? " votes" : " vote");
|
||||
document.getElementById("totalVotes").innerText = totalVotes;
|
||||
}
|
||||
|
||||
var bg1 = document.getElementById('background-stats-1');
|
||||
var bg2 = document.getElementById('background-stats-2');
|
||||
bg1.style.width = percentages.a + "%";
|
||||
bg2.style.width = percentages.b + "%";
|
||||
});
|
||||
|
||||
connection.start().catch(function (err) {
|
||||
|
@ -1,4 +0,0 @@
|
||||
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your Javascript code.
|
Loading…
Reference in New Issue
Block a user