# WebSocket

A WebSocket API do Azion Runtime permite que uma function atue como servidor ou como cliente WebSocket e transporte tráfego bidirecional para serviços de backend. A própria function aceita ou abre a conexão, o que diferencia esta API do [WebSocket Proxy](/pt-br/documentacao/plataforma/applications/websocket/), em que uma aplicação apenas transporta a conexão até um servidor WebSocket na sua origem. Use a WebSocket API para cargas de trabalho em tempo real, como chat, jogos multiplayer, dashboards de telemetria e fluxos de inferência de AI.

> **nota**
>
> Com `azion dev`, `upgradeWebSocket` e `WebSocket` não estão definidos. Uma chamada a `upgradeWebSocket()` lança `ReferenceError: upgradeWebSocket is not defined`, e `new WebSocket()` lança `TypeError: WebSocket is not a constructor`. Em uma function com deploy feito, os dois globais estão definidos como funções.

---

## Disponibilidade

A WebSocket API está disponível para clientes com Business, Enterprise ou Mission-Critical Support e para clientes com contrato de Reserva de Capacidade ou de Saving Plan. Para solicitar acesso, entre em contato com o [suporte técnico](/pt-br/documentacao/suporte/).

---

## Modos servidor e cliente

Uma function com deploy feito acessa os dois modos por meio de dois globais:

| Global                      | Modo     | Descrição                                                                                                                                                                                                 |
| --------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upgradeWebSocket(request)` | Servidor | Aceita o upgrade WebSocket de uma requisição recebida. Retorna um objeto com `response` e `socket`: retorne `response` do handler para concluir o upgrade e use `socket` para enviar e receber mensagens. |
| `WebSocket(url)`            | Cliente  | O construtor padrão `WebSocket`. Abre uma conexão WebSocket de saída da function para `url`.                                                                                                              |

`upgradeWebSocket()` aceita apenas uma requisição cujo header `upgrade` contém `websocket`. Chamada com qualquer outra requisição, a função lança `TypeError: Invalid Header: 'upgrade' header must contain 'websocket'`. Por isso, verifique o header antes da chamada, como faz o exemplo abaixo.

O Azion Runtime também oferece helpers que fazem o broadcast de uma mensagem para todos os clientes conectados, de modo que uma function pode distribuir uma mensagem para todas as conexões dela.

---

## Métricas e logs

A atividade WebSocket gera três eventos, que aparecem em [Real-Time Metrics](/pt-br/documentacao/plataforma/real-time-metrics/) e em [Data Stream](/pt-br/documentacao/plataforma/data-stream/) para ajudar você a monitorar conexões e mensagens:

- `websocket.connection.accepted`
- `message.sent`
- `message.received`

---

## Inspeção pelo firewall

As regras de um [firewall](/pt-br/documentacao/plataforma/firewall/) podem inspecionar o tráfego WebSocket antes que o upgrade seja concluído. Verifique se as regras do seu firewall deixam passar as conexões WebSocket que a sua function precisa aceitar.

---

## Exemplo

Este handler aceita um upgrade WebSocket quando a requisição traz `upgrade: websocket`, registra em log os eventos `open`, `message`, `close` e `error` do socket e responde a cada mensagem com `pong`. Qualquer outra requisição recebe uma página HTML cujo script abre uma conexão WebSocket de volta para o mesmo host:

```javascript
export default {
    async fetch(request, env, ctx) {
        // Check if the request is a WebSocket upgrade
        if (request.headers.get("upgrade") === "websocket") {
            // Use the upgradeWebSocket function to handle the WebSocket upgrade
            const { response, socket } = upgradeWebSocket(request);

            // Handle WebSocket events
            socket.addEventListener("open", () => {
                console.log("WebSocket connection established");
            });

            socket.addEventListener("message", (event) => {
                console.log(`Message received: ${event.data}`);
                socket.send("pong"); // Respond with "pong"
            });

            socket.addEventListener("close", () => {
                console.log("WebSocket connection closed");
            });

            socket.addEventListener("error", (error) => {
                console.error("WebSocket error:", error);
            });

            // Return the response to complete the WebSocket upgrade
            return response;
        }

        // If the request is not a WebSocket upgrade, serve a simple HTML page
        const htmlContent = `
            <!DOCTYPE html>
            <html>
            <head>
                <title>WebSocket Example</title>
            </head>
            <body>
                <h1>WebSocket Example</h1>
                <script>
                    const socket = new WebSocket("wss://" + location.host);
                    socket.onopen = () => console.log("WebSocket connected");
                    socket.onmessage = (event) => console.log("Message from server:", event.data);
                    socket.onclose = () => console.log("WebSocket disconnected");
                    socket.onerror = (error) => console.error("WebSocket error:", error);
                </script>
            </body>
            </html>
        `;

        return new Response(htmlContent, {
            status: 200,
            headers: { "Content-Type": "text/html" },
        });
    },
};
```

Uma function com deploy feito retorna esta resposta a uma requisição sem o header `upgrade`. O corpo é a página HTML, com as quebras de linha escapadas:

```json
{
 "status": 200,
 "statusText": "",
 "headers": {
  "content-type": "text/html"
 },
 "body": "\n            <!DOCTYPE html>\n            <html>\n            <head>\n                <title>WebSocket Example</title>\n            </head>\n            <body>\n                <h1>WebSocket Example</h1>\n                <script>\n                    const socket = new WebSocket(\"wss://\" + location.host);\n                    socket.onopen = () => console.log(\"WebSocket connected\");\n                    socket.onmessage = (event) => console.log(\"Message from server:\", event.data);\n                    socket.onclose = () => console.log(\"WebSocket disconnected\");\n                    socket.onerror = (error) => console.error(\"WebSocket error:\", error);\n                </script>\n            </body>\n            </html>\n        "
}
```

---

## Recursos relacionados

- [WebSocket Proxy](/pt-br/documentacao/plataforma/applications/websocket.md): Como uma aplicação transporta uma conexão WebSocket até um servidor na sua origem.
- [Handlers](/pt-br/documentacao/devtools/runtime/api-reference/handlers.md): O formato de handler que recebe a requisição e retorna a resposta de upgrade.
- [Request](/pt-br/documentacao/devtools/runtime/api-reference/request.md): Como uma function lê os headers da requisição recebida, como `upgrade`.
- [Web APIs](/pt-br/documentacao/devtools/runtime/api-reference/javascript.md): As outras Web APIs que o Azion Runtime suporta.
