Skip to content

20. Wdrożenie aplikacji klient-serwer na serwerze hostingowym

Poniżej przedstawiamy ogólne zasady wdrożenia aplikacji klient-serwer, którą opracowaliśmy, na serwerze OVH [https://www.ovh.com/fr/]. Wdrożenie u innych dostawców usług hostingowych nie powinno się znacznie różnić. Chcemy po prostu pokazać, że nasza aplikacja dobrze nadaje się do takiego wdrożenia.

20.1. Wdrożenie serwera

Wybrany hosting OVH to hosting podstawowy:

  1. środowisko PHP 7.3;
  2. SGBD MySQL;
  3. brak serwera [Redis];

Trzeci punkt wymaga od nas modyfikacji wersji 14 naszego serwera do obliczania podatków.

Image

Musimy zmodyfikować:

  • pliki konfiguracyjne [1];
  • kontrolery [AdminDataController] i [CalculerImpotController], aby uwzględnić fakt, że nie ma serwera [Redis];

Plik [config.json] zmienia się w następujący sposób:


{
    "databaseFilename": "Config/database.json",
    "corsAllowed": false,
    "redisAvailable":false,
    "rootDirectory": "/.../www/apps/impot/serveur-php7",
    "relativeDependencies": [

        "/Entities/BaseEntity.php",
        ...
        "/Controllers/AdminDataController.php"
    ],
    "absoluteDependencies": [
        "/.../vendor/autoload.php",
        "/.../vendor/predis/predis/autoload.php"
    ],
    "users": [
        {
            "login": "admin",
            "passwd": "admin"
        }
    ],
    ...
}

Komentarze

  • wiersz 4: dodano zmienną logiczną [redisAvailable], aby wskazać, czy mamy dostęp do serwera [Redis], czy nie;
  • wiersze 5, 13, 14: zmienią się ścieżki bezwzględne;

Plik [database.json] zmienia się w następujący sposób:


{
    "dsn": "mysql:host=...;dbname=...",
    "id": "...",
    "pwd": "...",
    "tableTranches": "dbimpots_tbtranches",
    "colLimites": "limites",
    "colCoeffR": "coeffr",
    "colCoeffN": "coeffn",
    "tableConstantes": "dbimpots_tbconstantes",
    "colPlafondQfDemiPart": "plafondQfDemiPart",
    ...
}

Uwagi

  • wiersze 2–4: identyfikator bazy danych oraz dane identyfikacyjne jej właściciela ulegną zmianie;

Kontroler [AdminDataController] ulega następującym zmianom:


<?php

namespace Application;

// zależności Symfony
use \Symfony\Component\HttpFoundation\Response;
use \Symfony\Component\HttpFoundation\Request;
use \Symfony\Component\HttpFoundation\Session\Session;
// alias warstwy [dao]
use \Application\ServerDaoWithSession as ServerDaoWithRedis;

class AdminDataController implements InterfaceController {

  // $config to konfiguracja aplikacji
  // przetwarzanie żądania Request
  // korzysta z sesji Session i może ją modyfikować
  // $infos to dodatkowe informacje specyficzne dla każdego kontrolera
  // zwraca tablicę [$statusCode, $état, $content, $headers]
  public function execute(
    array $config,
    Request $request,
    Session $session,
    array $infos = NULL): array {

    // musi być tylko jeden parametr GET
    $method = strtolower($request->getMethod());
    ...

    // można pracować
    // Redis
    if ($config["redisAvailable"]) {
      \Predis\Autoloader::register();
      ...
    } else {
      try {
        // pobieramy dane podatkowe z bazy danych
        $dao = new ServerDaoWithRedis($config["databaseFilename"], NULL);
        // taxAdminData
        $taxAdminData = $dao->getTaxAdminData();
      } catch (\Throwable $ex) {
        // nie poszło dobrze
        // zwracamy wynik z błędem do głównego kontrolera
        $état = 1051;
        return [Response::HTTP_INTERNAL_SERVER_ERROR, $état,
          ["réponse" => utf8_encode($ex->getMessage())], []];
      }
    }

    // zwraca wynik do głównego kontrolera
    $état = 1000;
    return [Response::HTTP_OK, $état, ["réponse" => $taxAdminData], []];
  }

}

Komentarze

  • wiersz 31: sprawdzane jest teraz, czy istnieje serwer o identyfikatorze [Redis];
  • wiersze 32–34: jeśli tak, poprzedni kod jest przejmowany w całości;
  • wiersze 35–46: w przeciwnym razie dane z urzędu skarbowego są pobierane z bazy danych;

Kontroler [CalculerImpotController], który również potrzebuje danych z urzędu skarbowego, zmienia się w identyczny sposób.

Gotowe. Wdrożenie na serwerze OVH polegało na utworzeniu FTP. Na OVH pobrano:

  • wersję [vuejs-14-without-redis];
  • plik [vendor], zawierający wszystkie zależności serwera [vuejs-14-without-redis];

Po zakończeniu transferu FTP wygenerowano tabele niezbędne dla serwera za pomocą następującego skryptu SQL:


-- phpMyAdmin SQL Zrzut
-- wersja 4.8.5
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Czas wygenerowania: 12 października 2019 r. o godz. 07:45 AM
-- Wersja serwera: 5.7.24
-- PHP Wersja: 7.2.11

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Struktura tabeli `dbimpots_tbconstantes`
--

CREATE TABLE `dbimpots_tbconstantes` (
  `id` int(11) NOT NULL,
  `plafondQfDemiPart` decimal(10,2) NOT NULL,
  `plafondRevenusCelibatairePourReduction` decimal(10,2) NOT NULL,
  `plafondRevenusCouplePourReduction` decimal(10,2) NOT NULL,
  `valeurReducDemiPart` decimal(10,2) NOT NULL,
  `plafondDecoteCelibataire` decimal(10,2) NOT NULL,
  `plafondDecoteCouple` decimal(10,2) NOT NULL,
  `plafondImpotCelibatairePourDecote` decimal(10,2) NOT NULL,
  `plafondImpotCouplePourDecote` decimal(10,2) NOT NULL,
  `abattementDixPourcentMax` decimal(10,2) NOT NULL,
  `abattementDixPourcentMin` decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Zrzut danych dla tabeli `dbimpots_tbconstantes`
--

INSERT INTO `dbimpots_tbconstantes` (`id`, `plafondQfDemiPart`, `plafondRevenusCelibatairePourReduction`, `plafondRevenusCouplePourReduction`, `valeurReducDemiPart`, `plafondDecoteCelibataire`, `plafondDecoteCouple`, `plafondImpotCelibatairePourDecote`, `plafondImpotCouplePourDecote`, `abattementDixPourcentMax`, `abattementDixPourcentMin`) VALUES
(8, '1551.00', '21037.00', '42074.00', '3797.00', '1196.00', '1970.00', '1595.00', '2627.00', '12502.00', '437.00');

-- --------------------------------------------------------

--
-- Struktura tabeli `dbimpots_tbtranches`
--

CREATE TABLE `dbimpots_tbtranches` (
  `id` int(11) NOT NULL,
  `limites` decimal(10,2) NOT NULL,
  `coeffR` decimal(10,2) NOT NULL,
  `coeffN` decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Zrzut danych dla tabeli `dbimpots_tbtranches`
--

INSERT INTO `dbimpots_tbtranches` (`id`, `limites`, `coeffR`, `coeffN`) VALUES
(36, '9964.00', '0.00', '0.00'),
(37, '27519.00', '0.14', '1394.96'),
(38, '73779.00', '0.30', '5798.00'),
(39, '156244.00', '0.41', '13913.69'),
(40, '0.00', '0.45', '20163.45');

--
-- Indeksy dla zrzuconych tabel
--

--
-- Indeksy dla tabeli `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
  ADD PRIMARY KEY (`id`);

--
-- Indeksy dla tabeli `dbimpots_tbtranches`
--
ALTER TABLE `dbimpots_tbtranches`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT dla zrzuconych tabel
--

--
-- AUTO_INCREMENT dla tabeli `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;

--
-- AUTO_INCREMENT dla tabeli `dbimpots_tbtranches`
--
ALTER TABLE `dbimpots_tbtranches`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=41;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Po wykonaniu tych czynności dostosowano pliki [config.json, database.json] do nowego środowiska.

20.2. Wdrożenie klienta [Vue.js]

Zdecydowano się wdrożyć klienta [Vue.js] na serwerach URL i [http://machine/apps/impot/client-vuejs/]. Spowodowało to następujące zmiany:

W katalogu głównym [workspace] utworzono następujący plik:

Image

Plik [vue.config.js] ma następującą treść:


// vue.config.js
module.exports = {
  // URL – serwis klienta [vuejs] – serwer obliczający podatek
  publicPath: '/apps/impot/client-vuejs/'
}

Plik [router.js] [3] również został zmodyfikowany:


// importy
import Vue from 'vue'
import VueRouter from 'vue-router'
...

// wtyczka routingu
Vue.use(VueRouter)

// trasy aplikacji
const routes = [
  ...
]

// router
const router = new VueRouter({
  // trasy
  routes,
  // tryb wyświetlania URL
  mode: 'history',
  // podstawowy URL aplikacji
  base: '/apps/impot/client-vuejs/'
})

// weryfikacja tras
router.beforeEach((to, from, next) => {
  ...
})

// eksport routera
export default router

Uwagi

  • wiersz 21: zmieniono podstawę pliku URL;

Plik [config.js] został zmodyfikowany w następujący sposób:


// korzystanie z biblioteki [axios]
const axios = require('axios');
// limit czasu żądań HTTP
axios.defaults.timeout = 5000;
// baza serwera obliczającego podatek URL
// schemat [https] powoduje problemy w przeglądarce Firefox, ponieważ serwer
// wysyła certyfikat z podpisem własnym. Działa poprawnie w przeglądarkach Chrome i Edge. Nie testowano w przeglądarce Safari.
// w przeglądarce Firefox jest to możliwe poprzez bezpośrednie wywołanie poniższego adresu URL i poinformowanie przeglądarki Firefox
//, że akceptujesz ryzyko związane z niepodpisanym certyfikatem. Wówczas klient [vuejs] będzie działał.
axios.defaults.baseURL = 'http://.../apps/impot/serwer-php7';
// będziemy używać plików cookie
axios.defaults.withCredentials = true;

// eksport konfiguracji
export default {
  // obiekt [axios]
  axios: axios,
  // maksymalny czas bezczynności sesji: 5 min = 300 s = 300 000 ms
  duréeSession: 300000
}

Komentarze

  • wiersz 10: umieszczono plik URL z serwera obliczającego podatek;

Wersja produkcyjna projektu została wygenerowana za pomocą polecenia [build] z pliku [package.json] [5] w następujący sposób:


{
  "name": "vuejs",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve vuejs-22/main.js",
    "build": "vue-cli-service build vuejs-22-ovh-withBootstrapVue/main.js",
    "lint": "vue-cli-service lint"
  },
  ...
}

Następnie folder [dist], zawierający wygenerowaną wersję produkcyjną, został „przesłany” na serwer OVH do folderu [/.../apps/impot], a następnie przemianowany na [client-vuejs], aby kod klienta znalazł się w folderze [/.../apps/impot/client-vuejs/], zgodnie z planem. Następnie do tego folderu pobraliśmy następujący plik [.htaccess]:


<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /apps/impot/client-vuejs/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /apps/impot/client-vuejs/index.html [L]
</IfModule>

Wynika to z faktu, że serwer WWW OVH używany w tym przypadku to serwer Apache. W przypadku innych typów serwerów należy zapoznać się z dokumentacją |https://cli.vuejs.org/guide/deployment.html|.

Aplikację serwerową PHP 7 można przetestować |ici|.

Klienta [Vue.js] można przetestować za pomocą |ici|.

20.3. Conclusion

Wersja [vuejs-21] nie była niezbędna. Stwierdzono, że wersja [vuejs-20] prawidłowo radziła sobie z wpisywanymi przez użytkownika danymi URL. Niemniej jednak nowa wersja zapewnia użytkownikowi dodatkowy komfort. Użytkownik może nawigować, wpisując URL. Aplikacja proponuje mu wówczas widok najlepiej odpowiadający aktualnemu stanowi (sesji) aplikacji. Ponadto wersja [vuejs-22] wprowadza ulepszenia dotyczące wyświetlania aplikacji na urządzeniach mobilnych.