rmpt / citizen-card-reader

4 stars 3 forks source link

Correr em windows #2

Closed MiguelQueiroz closed 7 months ago

MiguelQueiroz commented 1 year ago

Ola, É possível isto correr em windows? Descarrego o ficheiro fiz double click, não vi nada em background a correr, logo a chamadas como "servidor" não retornam nada.

Estou a fazer algo errado?

MiguelQueiroz commented 1 year ago

OK o commando no ficheiro readme estava mal java -jar citizer-card-reader-api.jar deve ser java -jar citizen-card-reader-api.jar

Apesar que agora abre, mas dá erro:

19:47:46.486 [main] ERROR o.s.b.w.e.tomcat.TomcatStarter MDC= - Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'mainConfig': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: C:\Users\MIGUEL\AppData\Local\Temp\citizen-card-native-lib11764646713135521085\pteidlibj.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform 19:47:46.546 [main] INFO o.a.catalina.core.StandardService MDC= - Stopping service [Tomcat]

"Can't load IA 32-bit .dll on a AMD 64-bit platform"

rmpt commented 1 year ago

Olá, sim, é possível correr em windows, só precisas de java e a app cartão de cidadao instalada. Tens a app correcta do cartão de cidadao instalada? O erro parece dizer que a lib que está a ser carregada é para 32 bits mas o teu CPU é de 64. Talvez tenhas instalado a versão 32 bits da app cartão de cidadão mas precisas da de 64 no teu computador.

MiguelQueiroz commented 1 year ago

Sim tenho, eu acho que é um problema com o dll , pteidlibj.dll que deve estar numa versão não compatível e depois quando é copiada para a tmp file, não corre. Onde foi buscar este ficheiro "pteidlibj.dll" existe em algum SDK do gov? Fazendo replace por um outro poderia posso compilar e ver se dá. É que tenho a versão 64 da app official do CC e o plugin. Obrigado!

MiguelQueiroz commented 1 year ago

Fiz fork e alterei a parte da utilização desse ddl, para utilizar diretamente do sdk o "PTEID_ReaderSet.initSDK();" fiz pull request. Thanks.

PINHOf commented 8 months ago

Boas, estou com o mesmo problema.

@rmpt O erro parece dizer que a lib que está a ser carregada é para 32 bits mas o teu CPU é de 64. Talvez tenhas instalado a versão 32 bits da app cartão de cidadão mas precisas da de 64 no teu computador.

Fiz download do site oficial, que vem com a versão 64 bits (imagem exemplificativa): image

Verifiquei a versão do Java: image

Ao executar o jar via linha de comandos obtenho o erro:

(...) org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
 Error creating bean with name 'mainConfig': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: C:\Users\mypc\AppData\Local\Temp\citizen-card-native-lib15689339438128496585\pteidlibj.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform

@MiguelQueiroz Testei a tua solução, fiz download do teu fork e criei o build sem alterar nada. Obtenho o erro:

(...) ERROR o.s.b.w.e.tomcat.TomcatStarter MDC= - Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'mainConfig': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: 'void pt.gov.cartaodecidadao.pteidlibJava_WrapperJNI.PTEID_ReaderSet_initSDK__SWIG_1()'

@rmpt Tentei ainda substituir o ficheiro C:\Program Files\Portugal Identity Card\sdk\Java\pteidlibj.jar na pasta do teu projecto citizen-card-reader-0.1\citizen-card-reader-lib\libs e fazer nova build, mas o erro persiste.

O que posso fazer mais para despistar o problema?


Resolvido: tive de actualizar a dll pteidlibj.dll.

  1. Fiz download via https://www.dllme.com/dll/files/pteidlibj?sort=version&arch=0x8664
  2. Substituí na pasta do projecto citizen-card-reader-lib\src\main\resources\pteid\win
  3. Fiz build nova & está a funcionar!
rmpt commented 7 months ago

@PINHOf obrigado pelo update, pelo erro Can't load IA 32-bit .dll on a AMD 64-bit platform ia-te propor instalar java e app CC 32 bits, mesmo tendo um cpu 64 bits (não faz sentido, mas só para experimentar).

Creio que tenho de adicionar as libs 64bits e alterar o código para carregar a dll de acordo com a arquitectura do SO. Vou dar uma olhada entretanto.

PINHOf commented 7 months ago

Isso era óptimo, visto que neste momento estou com duas builds: x86 e x64 dependendo do PC.

Aproveito para perguntar uma situação sobre os cors: no ficheiro Application.yml não tenho nada adicionado referente aos cors, nem quero, no entanto ao aceder localmente ao endpoint /readers via Javascript, obtenho o erro: Access to fetch at 'http://localhost:8080/ccard/readers' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Como é que desactivo por completo a validação? Visto ser um ambiente local, não interessa aplicar restrições.

fetch('http://localhost:8080/ccard/readers', 
{
  method: 'GET',
  headers: {},
})

Resolvido: não sei se é a forma mais adequada, mas no ficheiro MainConfig.kt pode ser adicionado uma configuração geral e não preencho nada no ficheiro Application.yml. Pelo que percebo, tu só permites preencher os campos cors e requiredHeader no ficheiro Application.yml que não me parece que funcione para o meu propósito (pelo menos eu não consegui colocar a funcionar...).

@Bean
open fun corsFilter(): CorsFilter {
    val corsConfiguration = CorsConfiguration()

    // Adicionado esta configuração geral
    corsConfiguration.apply {
        allowedOrigins = listOf("*")
        allowedMethods = listOf("*")
        allowedHeaders = listOf("*")
    }  

    if (appProperties.cors != null) {
        corsConfiguration.allowedOrigins = appProperties.cors!!.split(";")
    }
    if (appProperties.requiredHeader != null) {
        corsConfiguration.allowedHeaders = listOf(appProperties.requiredHeader!!.name)
    }
    corsConfiguration.allowedMethods = listOf("GET", "OPTIONS")
    val urlBasedCorsConfigurationSource = UrlBasedCorsConfigurationSource()
    urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration)
    return CorsFilter(urlBasedCorsConfigurationSource)
}
rmpt commented 7 months ago

Se não tinhas qualquer cors, o acesso a partir do localhost devia ser autorizado. Mas se não funciona adicionas http://localhost (com a devida porta se for o caso) aos cors que já funciona. Essa alteração que fizeste vai anular qualquer configuração cors que adiciones no futuro.

rmpt commented 7 months ago

@PINHOf podes por favor experimentar esta versão em win x86 e x64? Neste momento não tenho como experimentar, se pudesses dar essa ajuda, acelerava o processo :) https://drive.google.com/file/d/12hvNL0yEXK8PtyOizi4DyGZD5McJeiGR/view?usp=drive_link

PINHOf commented 7 months ago

Se não tinhas qualquer cors, o acesso a partir do localhost devia ser autorizado.

Também pensava, mas não o consigo. E, adicionado o cors conforme a documentação, também não aparenta funcionar. Testei assim:

app:
    cors: http://localhost, http://localhost:8080

De qualquer forma eu não quero qualquer tipo de cors, portanto aquela solução que coloquei funciona para mim.

Podes por favor experimentar esta versão em win x86 e x64? Neste momento não tenho como experimentar, se pudesses dar essa ajuda, acelerava o processo :)

Só consigo testar x64 e funcionou, portanto assumo que o x86 também está ok, obrigado!

rmpt commented 7 months ago

@PINHOf pelo teu bloco de código parece-me que a indentação do cors está errada. Não podes usar tabs, tens de usar 2 ou 4 espaços para a indentação. Experimenta com esta configuração, deve funcionar:

app:
  cors: http://localhost,http://localhost:8080

Sobre suporte para x86 e x64, vou agora criar uma nova release com essa alteração, já testei em win x86.

rmpt commented 7 months ago

Corrigido em 777100e.

PINHOf commented 7 months ago

Fiz download do jar 0.2, mandei executar e obtenho o erro:

[main] INFO  c.r.c.reader.peidlib.PteidlibLoader MDC= - Loading PTEID library....
[main] INFO  c.r.c.r.p.setup.PteidSetupFactory MDC= - Windows Operating System detected
[main] INFO  c.r.c.r.p.setup.PteidSetupWindows MDC= - Main lib 'pteidlibj.dll' copied to 'C:\Users\mypc\AppData\Local\Temp\citizen-card-native-lib9879579798870532693\pteidlibj.dll'
[main] ERROR o.s.b.w.e.tomcat.TomcatStarter MDC= - Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'mainConfig': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: C:\Users\mypc\AppData\Local\Temp\citizen-card-native-lib9879579798870532693\pteidlibj.dll: The specified procedure could not be found
[main] INFO  o.a.catalina.core.StandardService MDC= - Stopping service [Tomcat]
[main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext MDC= - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
[main] INFO  o.s.b.a.l.ConditionEvaluationReportLoggingListener MDC= -

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[main] ERROR o.s.boot.SpringApplication MDC= - Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat (...) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainConfig': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError:

Aproveito para perguntar, o endpoint de leitura do cartão está a demorar entre 10-15 segundos para obter resposta, isto deve-se sobretudo à aplicação gov. e não é possível melhorar correcto?

rmpt commented 7 months ago

O erro que estás a ter é porque não tens a última versão do cartão de cidadão instalada. Actualiza para a última versão. Sobre o tempo de espera, já tive situações semelhantes mas tinha a ver com o próprio cartão, havia uns cartões mais antigos ou com uma certa versão que eram muito lentos. Nunca cheguei a perceber a 100% o porquê, mas quanto a isso não há muito a fazer, infelizmente. Se tiveres mesmo de resolver isso, a minha sugestão é implementares um leitor de cartões de raiz, depois partilha pf 😁

PINHOf commented 7 months ago

Confirmo que o erro se deve a não ter a última versão. Já funciona.

Quanto ao resto, a tua solução é perfeita porque funciona como um servidor HTTP e permite-me aceder via Javascript à informação do cartão a partir de qualquer lado. Neste momento verifico o endpoint /ccard/data a cada 5s, não sei se poderá haver melhor alternativa (?).

Inicialmente ia fazer uma solução de raíz ou em C# ou em ElectronJS, que iria comunicar a informação lida via Websockets para um website, mas depois de encontrar a tua solução, não vale a pena. Realmente isto só peca por ser um bocadinho lento. No meu caso acontece o seguinte:

  1. Faço a chamada ao endpoint /ccard/data a cada 5s (significa que a pessoa pode ter o azar de estar estes 5s à espera...)
  2. Demora cerca de 10/15s a obter a resposta do endpoint
  3. Mostro a informação

Portanto o tempo de espera pode ser no pior das hipoteses 20s e na melhor das hipoteses 10s.

rmpt commented 7 months ago

A resposta dos 2 endpoints é rápida, a lentidão poderá estar em vários fatores. No laptop em si, no leitor de cartões, no cartão, etc. Nos meus testes com os cartões cá de casa a resposta é imediata, no pior dos casos 1 ou 2 segundos.

Não estou dentro do teu use case, mas porque estás a fazer polling dos leitores? Não é mais simples fazeres a leitura quando necessário? Ou seja, quando a pessoa abre a página fazer o request. Se entretanto desligares o leitor e tentares ler os dados, vais ter um erro. Mas aí podes apanhar o erro e fazer novo request. Ou ter um botão para explicitamente fazer refresh ao leitores. Enfim, é dificil opinar sem o contexto, de qualquer forma o polling não deveria ser problema, a resposta deveria levar no máximo 1 segundo. Já experimentaste com outro cliente tipo curl ou postman? Demora na mesma os tais 5s?

PINHOf commented 7 months ago

A resposta dos 2 endpoints é rápida, a lentidão poderá estar em vários fatores. No laptop em si, no leitor de cartões, no cartão, etc. Nos meus testes com os cartões cá de casa a resposta é imediata, no pior dos casos 1 ou 2 segundos.

Não coloco de parte esse problema, eu tenho este: https://1-life.eu/?product=1life-crcitizen Acabei de utilizar a própria App Gov, contei os segundos que demorou a carregar o meu cartão de cidadão e foram 11s !! Portanto acho que tens razão e é um problema da fraca qualidade do dispositivo.

Não estou dentro do teu use case, mas porque estás a fazer polling dos leitores? Não é mais simples fazeres a leitura quando necessário?

Relativamente ao meu use-case, trata-se de ler continuamente cartões de cidadão para autorizar entradas em estabelecimentos. Já está tudo a funcionar impecavelmente, só estava a tentar descortinar o delay.

Estou a utilizar regular-polling, mas vou tentar implementar long-polling. Obrigado pela ajuda e parabéns pela solução!

PINHOf commented 6 months ago

Como é que consegues ter feedback em 1/2 segundos? Qual o teu leitor de cartões?

@rmpt alguma sugestão? Tudo está a funcionar impecavelmente, mas o meu leitor de cartões, que custou cerca de 10/15€, demora literalmente 10 segundos na App Gov.pt após inserir o meu cartão de cidadão...e, claro, o mesmo acaba por acontecer com a tua solução.

Portanto, não é um problema da tua solução, mas sim ou do meu cartão de cidadão ou do dispositivo. O meu dispositivo é igual a um destes: image