如何仅使用标准库在Golang中实现WebSocket通信?

问题描述 投票:0回答:1

我正在用 Go 构建一个简单的聊天应用程序,并且希望在不使用任何外部库(例如 gorilla/websocket)的情况下实现 WebSocket 通信。我的目标是建立一个可以在两个用户之间发送和接收消息的 WebSocket 连接。

任何人都可以提供如何仅使用 Go 标准库设置 WebSocket 功能的基本示例吗?

go network-programming websocket
1个回答
0
投票

使用外部库会减少手动工作,但根据您的要求,我设法制作了一些应该的东西,在这里 ->

package main

import (
    "bufio"
    "bytes"
    "encoding/base64"
    "fmt"
    "net"
    "net/http"
    "strings"
    "time"
)

func main() {
    http.HandleFunc("/ws", wsHandler)
    fmt.Println("Starting server on :8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        fmt.Println("Server error:", err)
    }
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
    if r.Header.Get("Upgrade") != "websocket" {
        http.Error(w, "Not a WebSocket request", http.StatusBadRequest)
        return
    }

    conn, _, err := w.(http.Hijacker).Hijack()
    if err != nil {
        http.Error(w, "Failed to hijack connection", http.StatusInternalServerError)
        return
    }
    defer conn.Close()

    // WebSocket handshake
    key := r.Header.Get("Sec-WebSocket-Key")
    acceptKey := computeAcceptKey(key)
    responseHeaders := "HTTP/1.1 101 Switching Protocols\r\n" +
        "Upgrade: websocket\r\n" +
        "Connection: Upgrade\r\n" +
        "Sec-WebSocket-Accept: " + acceptKey + "\r\n\r\n"
    conn.Write([]byte(responseHeaders))

    // Simple print loop
    for {
        message, err := readMessage(conn)
        if err != nil {
            fmt.Println("Read error:", err)
            break
        }
        fmt.Println("Received:", string(message))
        if err := writeMessage(conn, message); err != nil {
            fmt.Println("Write error:", err)
            break
        }
    }
}

func computeAcceptKey(key string) string {
    magic := "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
    hash := sha1.Sum([]byte(key + magic))
    return base64.StdEncoding.EncodeToString(hash[:])
}

© www.soinside.com 2019 - 2024. All rights reserved.