O WebSocket fornece uma conexão bidirecional, de single-socket e full-duplex entre o servidor e o cliente, tornando a comunicação em tempo real muito mais eficiente do que outras maneiras, como eventos longos de sondagem e enviados pelo servidor Com o WebSocket, o cliente e o servidor podem falar independentemente, cada um capaz de enviar e receber informações ao mesmo tempo após o handshake inicial, reutilizando a mesma conexão do cliente para o servidor e o servidor para o cliente, o que reduz o atraso e o servidor carrega muito, permitindo que os aplicativos da web executem tarefas modernas da maneira mais eficaz. O protocolo WebSocket é suportado pela maioria dos principais navegadores, incluindo o Google Chrome, o Microsoft Edge, o Internet Explorer, o Firefox, o Safari e o Opera. Portanto, não há problemas de compatibilidade
- 1.Instale o pacote
github.com/gorilla/websocket
usando o comandogo get
$ go get github.com/gorilla/websocket
- 2.Crie
websocket-server.go
, onde faremos upgrade de uma solicitação HTTP para WebSocket, leremos a mensagem JSON do cliente e a transmitiremos para todos os clientes conectados
package main
import
(
"log"
"net/http"
"github.com/gorilla/websocket"
)
var clients = make(map[*websocket.Conn]bool)
var broadcast = make(chan Message)
var upgrader = websocket.Upgrader{}
type Message struct
{
Message string `json:"message"`
}
func HandleClients(w http.ResponseWriter, r *http.Request)
{
go broadcastMessagesToClients()
websocket, err := upgrader.Upgrade(w, r, nil)
if err != nil
{
log.Fatal("error upgrading GET request to a
websocket :: ", err)
}
defer websocket.Close()
clients[websocket] = true
for
{
var message Message
err := websocket.ReadJSON(&message)
if err != nil
{
log.Printf("error occurred while reading
message : %v", err)
delete(clients, websocket)
break
}
broadcast <- message
}
}
func main()
{
http.HandleFunc
(
"/", func(w http.ResponseWriter,
r *http.Request)
{
http.ServeFile(w, r, "index.html")
}
)
http.HandleFunc("/echo", HandleClients)
err := http.ListenAndServe(":8080", nil)
if err != nil
{
log.Fatal("error starting http server :: ", err)
return
}
}
func broadcastMessagesToClients()
{
for
{
message := <-broadcast
for client := range clients
{
err := client.WriteJSON(message)
if err != nil
{
log.Printf("error occurred while writing
message to client: %v", err)
client.Close()
delete(clients, client)
}
}
}
}
- 3.Rode no terminal
$ go run websocket-server.go
- Assim que executarmos o programa, o servidor WebSocket começará a escutar localmente na porta
8080
Entenda as partes
-
import ("log" "net/http" "github.com/gorilla/websocket")
que é um comando de pré-processamento que informa ao compilador Go para incluir todos os arquivos do log,net/http e github.com/gorilla./websocket
-
ar clients = make (map [* websocket.Conn] bool)
, criamos um mapa que representa os clientes conectados a um servidor WebSocket comKeyType
como um objeto de conexãoWebSocket
eValueType
como Boolean -
ar broadcast = make (chan Mensage)
, criamos um canal onde todas as mensagens recebidas são gravadas -
Definimos um manipulador
HandleClients
, que ao receber a solicitação HTTPGET
, atualiza para oWebSocket
, registra o cliente com o socket server, lê as mensagens JSON solicitadas e as grava no canal de transmissão -
Definimos uma função Go
broadcastMessagesToClients
, que captura as mensagens gravadas no canal de transmissão e as envia para todos os clientes atualmente conectados ao servidor WebSocket
O Debugging de um aplicativo da Web é uma das habilidades mais importantes para um desenvolvedor aprender, pois ajuda a identificar um problema, isola a origem do problema e corrige o problema ou determina uma maneira de contorná-lo
Para essa parte precisatemos de uma IDE, vou mostrar a configuração da IDE do GOLang a Goland da JetBrains
-
1.Clique em Open Project no GoLand IDE para abrir o websocket-server.go, que escrevemos antes
-
2.Quando o projeto for aberto, clique em Editar configurações
-
3.Selecione Adicionar nova configuração clicando no sinal +
-
4.Selecione Go Build, renomeie a configuração para WebSocket Local Debug, altere Run kind para Directory e clique em Apply e OK
-
5.Coloque alguns breakpoints e clique no botão Debug
-
Assim que executarmos o programa, o servidor WebSocket será iniciado localmente no modo de depuração, escutando na porta
8080
-
Navegar até
http://localhost:8080
nos mostrará a página do cliente WebSocket com uma caixa de texto e um botão Enviar -
Digite o texto e clique no botão Enviar para ver a execução do programa parar nos breakpoints que colocamos no GoLand IDE
Aprendemos como depurar um servidor WebSocket que está sendo executado localmente. Agora aprenderemos a depurá-lo se estiver sendo executado em outra máquina ou em uma máquina remota Etapas são parecidas com a anterior
-
1.Adicione outra configuração clicando em Editar configurações
-
2.Clique no sinal + para adicionar nova configuração e selecione Ir remoto
-
3.Renomeie a configuração de depuração para o
WebSocket Remote Debug
, altere o Host paraIP
ouDNS
da máquina remota e clique em Aplicar e OK -
4.Execute um servidor Delve sem cabeçalho no computador de destino ou remoto executando o seguinte comando
https://www.jetbrains.com/go/
O comando anterior iniciará um servidor de API escutando na porta 2345
- 5.Selecione WebSocket Remote Debug configuration e clique no botão Debug
- Selecione WebSocket Remote Debug configuration e clique no botão Debug e irá aparecer a mensagem
Hello Arpit
Testes unitários ou desenvolvimento orientado a testes (TDD - test-driven development) ajudam o desenvolvedor a projetar código acoplado com foco na reutilização de código. Também nos ajuda a perceber quando parar de codificar e fazer alterações rapidamente
-
Vamos utilizar o WebSocker server que fizemos antes
-
1.Instale os pacotes
github.com/gorilla/websocket
egithub.com/stretchr/testify/assert
usando o comandogo get
$ go get github.com/gorilla/websocket
$ go get github.com/stretchr/testify/assert
- 2.Crie
websocket-server_test.go
onde criaremos um servidor de teste, conectaremos a ele usando o cliente Gorilla e, eventualmente, leremos e escreveremos mensagens para testar a conexão
package main
import
(
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
)
func TestWebSocketServer(t *testing.T)
{
server := httptest.NewServer(http.HandlerFunc
(HandleClients))
defer server.Close()
u := "ws" + strings.TrimPrefix(server.URL, "http")
socket, _, err := websocket.DefaultDialer.Dial(u, nil)
if err != nil
{
t.Fatalf("%v", err)
}
defer socket.Close()
m := Message{Message: "hello"}
if err := socket.WriteJSON(&m); err != nil
{
t.Fatalf("%v", err)
}
var message Message
err = socket.ReadJSON(&message)
if err != nil
{
t.Fatalf("%v", err)
}
assert.Equal(t, "hello", message.Message, "they
should be equal")
}
- Execute
go test
$ go test websocket-server_test.go websocket-server.go
ok command-line-arguments 0.048s
-
Isso nos dará a resposta ok, o que significa que o teste foi compilado e executado com sucesso
-
Vamos ver como fica quando um teste Go falha. Altere a saída esperada na instrução assert para outra coisa. No seguinte
Hello
foi alterado paraHi
...
assert.Equal(t, "hi", message.Message, "they should be equal")
...
- Execute o
go teste
de novo
$ go test websocket-server_test.go websocket-server.go
- Ele nos fornecerá a resposta de falha junto com o rastreio de erro