Skip to content

20. Implantação do aplicativo cliente/servidor em um serviço de hospedagem

Apresentamos aqui as linhas gerais da implantação do aplicativo cliente/servidor que desenvolvemos em um servidor OVH [https://www.ovh.com/fr/]. A implantação em outros provedores de hospedagem não deve ser muito diferente. Queremos simplesmente mostrar que nosso aplicativo se adapta bem a essa implantação.

20.1. Implantação do servidor

A hospedagem OVH em questão é uma hospedagem básica:

  1. um ambiente PHP 7.3;
  2. um SGBD MySQL;
  3. sem servidor [Redis];

O terceiro ponto nos obriga a modificar a versão 14 do nosso servidor de cálculo de impostos.

Image

Precisamos modificar:

  • os arquivos de configuração [1];
  • os controladores [AdminDataController] e [CalculerImpotController] para levar em conta o fato de que não há servidor [Redis];

O arquivo [config.json] passa a ter a seguinte forma:


{
    "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"
        }
    ],
    ...
}

Comentários

  • linha 4: introduz-se uma variável booleana [redisAvailable] para indicar se há ou não acesso a um servidor [Redis];
  • linhas 5, 13, 14: os caminhos absolutos serão alterados;

O arquivo [database.json] é alterado da seguinte forma:


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

Comentários

  • linhas 2-4: a identificação do banco de dados, bem como os identificadores de seu proprietário, serão alterados;

O controlador [AdminDataController] sofre as seguintes alterações:


<?php

namespace Application;

// dependências do Symfony
use \Symfony\Component\HttpFoundation\Response;
use \Symfony\Component\HttpFoundation\Request;
use \Symfony\Component\HttpFoundation\Session\Session;
// alias da camada [dao]
use \Application\ServerDaoWithSession as ServerDaoWithRedis;

class AdminDataController implements InterfaceController {

  // $config é a configuração do aplicativo
  // processamento de uma solicitação Request
  // utiliza a sessão Session e pode modificá-la
  // $infos são informações adicionais específicas de cada controlador
  // retorna um array [$statusCode, $état, $content, $headers]
  public function execute(
    array $config,
    Request $request,
    Session $session,
    array $infos = NULL): array {

    // deve haver um único parâmetro GET
    $method = strtolower($request->getMethod());
    ...

    // é possível trabalhar
    // Redis
    if ($config["redisAvailable"]) {
      \Predis\Autoloader::register();
      ...
    } else {
      try {
        // vamos buscar os dados fiscais no banco de dados
        $dao = new ServerDaoWithRedis($config["databaseFilename"], NULL);
        // taxAdminData
        $taxAdminData = $dao->getTaxAdminData();
      } catch (\Throwable $ex) {
        // deu errado
        // resultado devolvido com erro ao controlador principal
        $état = 1051;
        return [Response::HTTP_INTERNAL_SERVER_ERROR, $état,
          ["réponse" => utf8_encode($ex->getMessage())], []];
      }
    }

    // resultado devolvido ao controlador principal
    $état = 1000;
    return [Response::HTTP_OK, $état, ["réponse" => $taxAdminData], []];
  }

}

Comentários

  • linha 31: agora é verificado se existe ou não um servidor [Redis];
  • linhas 32-34: se sim, o código anterior é retomado na íntegra;
  • linhas 35-46: caso contrário, os dados da administração fiscal são obtidos do banco de dados;

O controlador [CalculerImpotController], que também precisa dos dados da administração fiscal, funciona da mesma forma.

Pronto. A implantação no servidor OVH consistiu em criar o FTP. Baixamos no OVH:

  • a versão [vuejs-14-without-redis];
  • a pasta [vendor], que contém todas as dependências do servidor [vuejs-14-without-redis];

Após a transferência do FTP, geramos as tabelas necessárias para o servidor com o seguinte script SQL:


-- phpMyAdmin SQL Dump
-- versão 4.8.5
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Hora de geração: 12 de outubro de 2019 às 07:45 AM
-- Versão do servidor: 5.7.24
-- PHP Versão: 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 */;

--
-- Estrutura da tabela `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;

--
-- Exportação de dados da tabela `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');

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

--
-- Estrutura da tabela `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;

--
-- Exportando dados da tabela `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');

--
-- Índices das tabelas exportadas
--

--
-- Índices da tabela `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
  ADD PRIMARY KEY (`id`);

--
-- Índices para a tabela `dbimpots_tbtranches`
--
ALTER TABLE `dbimpots_tbtranches`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT para tabelas exportadas
--

--
-- AUTO_INCREMENT para a tabela `dbimpots_tbconstantes`
--
ALTER TABLE `dbimpots_tbconstantes`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;

--
-- AUTO_INCREMENT para a tabela `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 */;

Quando tudo isso foi concluído, adaptamos os arquivos [config.json, database.json] ao seu novo ambiente.

20.2. Implantação do cliente [Vue.js]

Foi decidido implantar o cliente [Vue.js] no URL e no [http://machine/apps/impot/client-vuejs/]. Isso resultou nas seguintes alterações:

Na raiz do [workspace] do [VSCode], foi criado o seguinte arquivo [vue.config.js]:

Image

O arquivo [vue.config.js] é o seguinte:


// vue.config.js
module.exports = {
  // o URL do serviço de atendimento ao cliente [vuejs] do servidor de cálculo de impostos
  publicPath: '/apps/impot/client-vuejs/'
}

O arquivo [router.js] [3] também foi modificado:


// importações
import Vue from 'vue'
import VueRouter from 'vue-router'
...

// plug-in de roteamento
Vue.use(VueRouter)

// rotas do aplicativo
const routes = [
  ...
]

// o roteador
const router = new VueRouter({
  // as rotas
  routes,
  // o modo de exibição do URL
  mode: 'history',
  // o URL básico do aplicativo
  base: '/apps/impot/client-vuejs/'
})

// verificação das rotas
router.beforeEach((to, from, next) => {
  ...
})

// exportação do roteador
export default router

Comentários

  • linha 21: a base do arquivo URL foi alterada;

O arquivo [config.js] foi alterado da seguinte forma:


// uso da biblioteca [axios]
const axios = require('axios');
// tempo limite das solicitações HTTP
axios.defaults.timeout = 5000;
// a base de dados do servidor de cálculo de impostos URL
// o esquema [https] apresenta problemas no Firefox porque o servidor de cálculo
// de cálculo de impostos envia um certificado autoassinado. Funciona bem com o Chrome e o Edge. O Safari não foi testado.
// no Firefox, é possível acessar o URL abaixo diretamente e informar ao Firefox
// que você aceita o risco de um certificado não assinado. Depois disso, o cliente [vuejs] funcionará.
axios.defaults.baseURL = 'http://.../apps/impot/servidor-php7';
// vamos usar cookies
axios.defaults.withCredentials = true;

// exportação da configuração
export default {
  // objeto [axios]
  axios: axios,
  // tempo máximo de inatividade da sessão: 5 min = 300 s = 300.000 ms
  duréeSession: 300000
}

Comentários

  • linha 10: insere-se o URL do servidor de cálculo de impostos;

A versão de produção do projeto foi gerada com o comando [build] do arquivo [package.json] [5] a seguir:


{
  "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"
  },
  ...
}

Feito isso, a pasta [dist], que continha a versão de produção gerada, foi “carregada” no servidor OVH, na pasta [/.../apps/impot], e renomeada como [client-vuejs] para que o código do cliente ficasse na pasta [/.../apps/impot/client-vuejs/], conforme previsto. Em seguida, nessa pasta, baixamos o seguinte arquivo [.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>

Isso porque o servidor web do OVH utilizado aqui é um servidor Apache. Para outros tipos de servidores, consulte a documentação |https://cli.vuejs.org/guide/deployment.html|.

O aplicativo de servidor PHP 7 pode ser testado |aqui|.

O cliente [Vue.js] pode ser testado |aqui|.

20.3. Conclusion

A versão [vuejs-21] não era indispensável. Verificou-se que a versão [vuejs-20] respondia corretamente aos URL digitados pelo usuário. No entanto, a nova versão oferece um conforto adicional ao usuário. Ele pode navegar digitando URL. O aplicativo então sugere a tela mais adequada ao estado atual (a sessão) do aplicativo. Além disso, a versão [vuejs-22] traz melhorias para a exibição do aplicativo em dispositivos móveis.