WEB3DEV

Cover image for Tutorial Nim-libp2p: Um Exemplo de Chat Ponto a Ponto (1)
Panegali
Panegali

Posted on • Atualizado em

Tutorial Nim-libp2p: Um Exemplo de Chat Ponto a Ponto (1)

Este artigo é o primeiro de uma série de três.

Olá a todos, bem-vindos ao primeiro artigo da série de tutoriais da nim-libp2p!

Este tutorial é para todos que estão interessados ​​em construir aplicativos de chat ponto a ponto. Nenhuma experiência de programação em Nim é necessária.

Para dar uma visão geral rápida, Nim é a linguagem de programação que estamos usando e nim-libp2p é a implementação Nim de libp2p, uma biblioteca modular que permite o desenvolvimento de aplicativos de rede ponto a ponto.

Hoje vamos orientá-lo através de um exemplo de chat ponto a ponto. O código completo pode ser encontrado em nosso repositório principal directchat.nim. O código para esta parte está em start.nim.

Espero que seja útil em sua jornada de aprendizado. Boa programação! ;)

Nota: Este tutorial está dividido em três partes conforme abaixo:

  • Parte I (agora): Configure a função principal e use multi-thread para processar entrada e saída.
  • Parte II: Discar ponto remoto e permitir comandos de entrada personalizados para usuários.
  • Parte III: Configurar e estabelecer um nó libp2p.

Antes que você comece

O único pré-requisito aqui é o Nim, a linguagem de programação com uma sintaxe semelhante ao Python e um desempenho semelhante ao C. Informações detalhadas podem ser encontradas aqui.

Executando o Exemplo

Primeiro, abra seu terminal e clone o repositório git que contém nosso código de exemplo.

git clone https://github.com/status-im/nim-libp2p.git
Enter fullscreen mode Exit fullscreen mode

Em seguida, instale as dependências.

cd nim-libp2p
nimble install
Enter fullscreen mode Exit fullscreen mode

Navegue até a pasta de exemplos.

cd examples
Enter fullscreen mode Exit fullscreen mode

Tente compilar e executar o código para ter certeza de que tudo está funcionando.

nim c -r --threads:on directchat.nim
# Isto equivale a: nim compile --run --threads:on directchat.nim
# --threads:on significa ativar o suporte para multi-threading
Enter fullscreen mode Exit fullscreen mode

Você está pronto para prosseguir se vir a seguinte saída:

1 Saída do terminal após executar directchat.nim

Comece a codificar!

Nesta seção, passaremos pelo código linha por linha, começando do básico. Sinta-se à vontade para pular se você já for muito experiente em Nim.

Configure o procedimento principal

Vamos primeiro criar uma função (chamada procedure em Nim) que imprime uma string "hi"!

  1. Crie um novo arquivo chamado start.nim no diretório tutorial
  2. Copie e cole o seguinte código em nosso novo arquivo.
import chronos

proc main() {.async.} =
  echo "hi"

when isMainModule:
  waitFor(main())
Enter fullscreen mode Exit fullscreen mode

A primeira linha importa o módulo " chronos ", que é uma biblioteca eficiente para programação assíncrona. Desenvolvido pela Status, o chronos começou como uma bifurcação da biblioteca padrão Nim async, mas desde então divergiu significativamente. Você pode encontrar mais documentação, notas e exemplos em seu Wiki.

Então, a palavra chave proc define nosso procedimento principal com o nome main. A sintaxe {. .} é chamada pragma em Nim. A palavra-chave async nele diz ao compilador para habilitar os recursos assíncronos para nosso procedimento.

A parte final deste código espera que nosso procedimento principal assíncrono seja executado pela palavra chave waitFor. Na penúltima linha há uma constante especial isMainModule, que será true quando este módulo for compilado como arquivo principal.

  1. Tente executar o trecho acima digitando-o no terminal. Você deve ver "hi" sendo impresso.
cd ../tutorial
nim c -r start.nim
Enter fullscreen mode Exit fullscreen mode

2 Saída do terminal após executar start.nim

Ler e processar a entrada do console

Neste exemplo, esperamos processar nossos procedimentos enquanto acessamos a entrada do usuário. Para conseguir isso, usaremos multi-threading.

Primeiro, crie um procedimento para acessar a entrada do usuário.

proc readInput(wfd: AsyncFD) {.thread.} =
  ## Este procedimento realiza a leitura de `stdin` e envia dados
  ## linha para a thread principal.
  let transp = fromPipe(wfd)

  while true:
    let line = stdin.readLine()
    discard waitFor transp.write(line & "\r\n")
Enter fullscreen mode Exit fullscreen mode

Neste procedimento, usamos while true para acessar continuamente a entrada do usuário de stdin e gravar o resultado em nosso descritor de arquivo de gravação wfd. A entrada será então encaminhada para rfd ser processada posteriormente.

Criar outro procedimento para imprimir a entrada.

proc processInput(rfd: AsyncFD) {.async.} =
  echo "Type something below to see if the multithread IO works:\nType 'exit' to exit."

  let transp = fromPipe(rfd)
  while true:
    let a = await transp.readLine()

    if a == "exit":
      quit(0);

    echo "You just entered: " & a
Enter fullscreen mode Exit fullscreen mode

Leia mais sobre o que é pipe, stdin, stdout e descritor de arquivo neste blog. Em resumo, o pipe é para conectar a entrada e a saída padrão aqui.

Aqui você pode ver que quando o usuário digita "exit", o programa finaliza com quit(0) onde 0 significa sair sem erros.

Em seguida, edite nosso procedimento principal para criar um conexão para enviar dados entre diferentes threads e atribuir seu manipulador à nova instância com base em nosso objeto.

proc main() {.async.} =
  let (rfd, wfd) = createAsyncPipe()
  if rfd == asyncInvalidPipe or wfd == asyncInvalidPipe:
    raise newException(ValueError, "Could not initialize pipe!")

  var thread: Thread[AsyncFD]
  thread.createThread(readInput, wfd)

  await processInput(rfd)
Enter fullscreen mode Exit fullscreen mode

Na primeira parte do código, rfd significa ler descritor de arquivo e wfd significa gravar descritor de arquivo. createAsyncPipe configura e retorna um conexão assíncrona que encaminha os dados gravados em wfd para serem lidos no rfd. Exceções são geradas se o valor de retorno for inválido.

A parte restante é autoexplicativa. Criamos uma thread para acessar continuamente a entrada do usuário e, em seguida, processar nossos dados de entrada.

Outra coisa a observar é que usamos var em vez de palavra chave let ao declarar thread porque let requer inicialização e o valor não pode ser alterado uma vez atribuído. Nós apenas especificamos o tipo de thread mas não damos o valor inicial aqui.

Por fim, lembro nosso usuário de adicionar a opção threads:on de multi-threading ao executar nosso script. Adicione esta linha antes de nossa instrução de importação.

when not(compileOption("threads")):
  {.fatal: "Please, compile this program with the --threads:on option!".}
Enter fullscreen mode Exit fullscreen mode

Execute start.nim e veja se seu input/output funciona bem. Lembre-se de adicionar threads:on aqui, pois estamos usando multi-thread.

nim c -r --threads:on start.nim 
Enter fullscreen mode Exit fullscreen mode

3- Saída do terminal após executar start.nim.

Conclusão

Agora você aprendeu a sintaxe básica do Nim e tem um script totalmente funcional para usar multi-threading facilmente para processar entrada e saída.

No próximo tutorial, veremos como chamar um ponto remoto e permitir que o usuário insira comandos personalizados. Fique ligado!


Este artigo foi publicado por Lee Ting Ting e traduzido por Marcelo Panegali. Seu original em inglês pode ser encontrado aqui.

Latest comments (0)