Wasabi v2.3.6
Essa versão traz uma reestruturação interna significativa junto com algumas mudanças de comportamento pontuais. A API pública continua praticamente compatível com a v2.3.5, com exceção de duas funções renomeadas. A maior parte do que mudou fica por baixo dos panos: organização mais limpa do código, primitivas criptográficas mais sólidas, melhor documentação das estruturas internas e uma base mais estável para o sistema async introduzido no ciclo anterior.
Breaking Changes
WebSocketSend renomeada para WebSocketSendText
WebSocketReceive renomeada para WebSocketReceiveText
Os nomes antigos não existem mais. A renomeação foi feita para alinhar com as contrapartes binárias (WebSocketSendBinary, WebSocketReceiveBinary) e deixar o propósito de cada função óbvio de cara. Um find-and-replace global em qualquer workbook que chame essas funções é tudo que precisa.
Segurança
Substituída RtlGenRandom por BCryptGenRandom
A geração interna de bytes aleatórios usada para as masking keys dos frames WebSocket chamava RtlGenRandom (exportada da advapi32.dll pelo alias não documentado SystemFunction036). Funcionava na prática, mas depender de um export não documentado não é algo pra manter no longo prazo. A chamada agora passa por BCryptGenRandom da bcrypt.dll com a flag BCRYPT_USE_SYSTEM_PREFERRED_RNG, que é o caminho documentado e suportado para bytes criptograficamente seguros no Windows Vista em diante. O comportamento externo é idêntico; é uma correção puramente interna.
Modelo Async por Eventos (Experimental)
Essa funcionalidade é experimental. O mecanismo por baixo envolve subclassing nativo de janela Win32 via thunk de machine code, o que traz algumas restrições sérias que você precisa conhecer antes de usar em produção.
O modelo async introduzido na versão anterior está melhor documentado e estabilizado agora, mas o mecanismo de subclassing ainda tem pontas afiadas:
Não edite código no VBE enquanto uma conexão async estiver ativa. Fazer isso vai travar o aplicativo host. O thunk guarda um ponteiro pro runtime do VBA, e o processo de reset de projeto do VBE não dá chance pro Wasabi limpar antes de destruir o runtime.
Não use o botão de Pausar (quadrado amarelo) no VBE enquanto o async estiver rodando. Isso também dispara um reset de projeto e vai causar crash pelo mesmo motivo.
A forma correta de encerrar uma sessão async é:
- Chamar
WebSocketDisconnectouWebSocketDisconnectAllpelo seu código, que desregistra o socket doWSAAsyncSelect, restaura o procedimento de janela original, destrói a janela oculta e libera a memória do thunk. - Clicar no botão de Redefinir (quadrado azul) no VBE, mas só depois de chamar uma das funções de desconexão. Clicar em Redefinir sem desconectar antes não é seguro.
O thunk tem um guard que tenta detectar se o runtime do VBA ainda está ativo antes de despachar, mas a limpeza explícita é a única abordagem confiável. Trate isso da mesma forma que trataria qualquer recurso não gerenciado.
O resto do modelo async funciona como descrito na referência da API. O objeto handler precisa ser guardado em nível de módulo ou workbook, os cinco métodos de callback precisam estar implementados, e a conexão já precisa estar estabelecida antes de chamar WasabiUseAsync.
Organização do Código
O módulo foi reorganizado num layout de seções numeradas para facilitar a navegação no VBE, que não tem uma view de outline de arquivo:
1. API Declarations
2. Constants
3. Types & Structs
4. Enums
5. Global Variables
6. Low-Level Memory & Thunks
7. Windows Messaging & Async Core
8. Time & Buffer Utilities
9. Connection Pool Management
10. Network Infrastructure (MTU, Proxy, TCP, Certificates)
11. WebSocket Protocol Core
12. TCP/Buffering Core
13. MQTT Protocol Core
14. Middleware & Queueing
15. Public APIs (TCP, WebSocket, MQTT, Compression)
Mudança puramente organizacional. Nenhuma lógica foi movida ou alterada como parte da reestruturação; o diff entre as seções reflete só declarações reposicionadas e agrupamentos renomeados.
Todos os constantes, enums e definições de tipo também foram movidos para suas respectivas seções em vez de ficarem espalhados. WasabiError, MqttPacketType e WasabiConnectionMode agora vivem na seção 4 junto com os outros enums. Constantes como BUFFER_SIZE, MSG_QUEUE_SIZE e as constantes de socket/TLS/crypto estão agrupadas na seção 2 com comentários indicando a qual subsistema pertencem.
Documentação Interna
Todos os tipos privados, structs e funções principais agora têm comentários de bloco no estilo JSDoc descrevendo seu propósito e campos. Útil principalmente se você precisar ler ou modificar os internos, e também facilita seguir o fluxo de dados entre as camadas TLS, WebSocket e MQTT quando algo dá errado e você precisa rastrear o problema.
O cabeçalho de licença também foi atualizado para o formato de bloco JSDoc, consistente com o resto do arquivo.
Correções e Melhorias Menores
INVALID_SOCKET agora é declarado uma vez por alvo de compilação (64-bit ou 32-bit) no topo da seção de variáveis globais, removendo o bloco #If VBA7 redundante que re-declarava no meio do arquivo.
A declaração do tipo HOSTENT64 foi movida para a seção de tipos junto com HOSTENT32, onde faz sentido estar. Antes estava declarada bem mais abaixo no arquivo, longe das outras structs de rede.
A constante BCRYPT_USE_SYSTEM_PREFERRED_RNG agora é declarada explicitamente em vez de ser inlined como número mágico, consistente com como toda outra constante Win32 é tratada no módulo.
Notas para Quem Está Atualizando da v2.3.5
A única mudança que vai quebrar código existente é a renomeação de WebSocketSend e WebSocketReceive. Todo o resto é interno ou aditivo. Se o seu código não chama nenhuma dessas duas funções diretamente, a atualização é um drop-in.
Se você está usando o modelo async da v2.3.5, nada mudou na interface pública. As restrições descritas na seção experimental acima já existiam na v2.3.5; só estão documentadas explicitamente aqui pela primeira vez.
GitHub: https://github.com/uesleibros/wasabi
Release: https://github.com/uesleibros/wasabi/releases/tag/v2.3.6-beta