Conexões de Rede

Como comunicar sua cena com servidores e APIs externas.

Sua cena pode aproveitar serviços externos que expõem APIs; você pode usar isso para obter dados de preços atualizados, dados meteorológicos ou qualquer outro tipo de informação exposta por uma API.

Você também pode configurar seu próprio servidor externo para ajudar sua cena e sincronizar dados entre seus jogadores. Isso pode ser feito com um servidor que expõe uma API REST ou com um servidor que usa WebSockets.

Chamar uma API REST

O código da sua cena pode enviar chamadas para uma API REST para buscar dados.

Como o servidor pode levar tempo para enviar sua resposta, você deve executar este comando como uma função assíncronaarrow-up-right, usando executeTask().

executeTask(async () => {
	try {
		let response = await fetch(callUrl)
		let json = await response.json()
		console.log(json)
	} catch {
		console.log('falha ao alcançar a URL')
	}
})

O comando fetch também pode incluir um segundo argumento opcional que agrupa headers, método HTTP e corpo HTTP em um único objeto.

  • url: Endereço para enviar a requisição

  • init: Um FlatFetchInit objeto que pode conter:

    • method : Método HTTP a ser usado (GET, POST, DELETE, etc)

    • body: Conteúdo do corpo da requisição. Deve ser enviado como um objeto JSON transformado em string.

    • headers: Headers adicionais para incluir na requisição. Headers relacionados à assinatura são adicionados automaticamente.

    • redirect: Estratégia de redirecionamento ('follow' | 'error' | 'manual')

    • responseBodyType: Especifica se o corpo da resposta é 'text' ou 'json'

    • timeout: Quanto tempo esperar por uma resposta antes que a requisição falhe. Por padrão 30000 milissegundos (30 segundos).

O comando fetch retorna um response objeto com os seguintes dados:

  • headers: Um ReadOnlyHeaders objeto. Chame o get() método para obter um header específico, ou o has() método para verificar se um header está presente.

  • ok: Booleano

  • redirected: Booleano

  • status: Número do código de status

  • statusText: Texto para o código de status

  • type: Terá um dos seguintes valores: basic, cors, default, error, opaque, opaqueredirect

  • url: URL que foi enviada

  • json(): Obter o corpo em formato JSON.

  • text(): Obter o corpo como texto.

circle-exclamation
circle-exclamation

Requisições assinadas

Você pode empregar uma medida extra de segurança para certificar que uma requisição se origina de uma sessão de jogador dentro do Decentraland. Você pode enviar suas requisições com uma assinatura adicional, que é assinada usando uma chave efêmera que a sessão Decentraland gera para cada jogador com base no endereço do jogador. O servidor que recebe a requisição pode então verificar se a mensagem assinada realmente corresponde a um endereço que está atualmente ativo no mundo.

Esse tipo de medida de segurança é especialmente valiosa quando pode haver um incentivo para um jogador abusar do sistema, para farmar tokens ou pontos em um jogo.

Para enviar uma requisição assinada, tudo o que você precisa fazer é usar o signedFetch() função, exatamente da mesma maneira que você usaria o fetch() função.

A requisição inclui uma série adicional de headers, contendo uma mensagem assinada e um conjunto de metadados para interpretá-la. A mensagem assinada consiste em todo o conteúdo da requisição criptografado usando a chave efêmera do jogador.

O signedFetch() difere da fetch() função no sentido de que a resposta é uma promessa de uma mensagem http completa, expressa como um FlatFetchResponse objeto. Isto inclui as seguintes propriedades:

  • body

  • headers

  • ok

  • status

  • statusText

determina quanta importância essa animação terá na média. body é considerada uma string, que você pode analisar como no exemplo acima. Se o corpo da resposta estiver em formato json, você pode especificar isso no responseBodyType e então acessar isso a partir da json propriedade na response.

Validando uma requisição assinada

Para fazer uso de requisições assinadas, o servidor que as recebe deve validar que as assinaturas correspondem ao restante da requisição e que o timestamp codificado dentro da mensagem assinada está atual.

Você pode encontrar um exemplo simples de um servidor realizando essa tarefa na cena exemplo a seguir:

Validar autenticidade do jogadorarrow-up-right

Tempo limite da requisição

Se uma requisição HTTP demorar muito para ser respondida, ela falha para que outras requisições possam ser enviadas. Para ambos fetch() e signedFetch(), o limite de tempo padrão é de 30 segundos, mas você pode atribuir um valor diferente em cada requisição configurando a timeout propriedade em qualquer uma das duas funções. O valor de timeout é expresso em milissegundos.

Usar WebSockets

Você também pode enviar e obter dados de um servidor WebSocket, desde que esse servidor use uma conexão segura com wss.

A sintaxe para usar WebSockets não difere da implementada nativamente pelo JavaScript. Veja a documentação da Mozilla Web APIarrow-up-right para detalhes sobre como capturar e enviar mensagens por WebSockets.

circle-info

💡 Tip: Uma biblioteca que simplifica o uso de conexões websocket e que se mostrou funcionar muito bem com o Decentraland é Colyseusarrow-up-right. Várias outras bibliotecas websocket não são compatíveis com o SDK do Decentraland.

Ela constrói uma camada de abstração acima das conexões websocket que facilita reagir a mudanças e armazenar um estado de jogo consistente remotamente no servidor. Você pode vê-la em ação nestes exemplos:

Depuração de requisições de rede

Você pode depurar requisições de rede abrindo o Debug Panel.

Para abrir o Debug Panel, você pode clicar no  ícone no canto superior direito. Então selecione a Requisições Web aba e clique Abrir Chrome Devtools.

Isso abrirá uma nova janela do Chrome com a aba Network aberta.

Veja Depurar em previewarrow-up-right para mais detalhes.

Atualizado