基於 Golang 和 WebSocket 實現屏幕共享方案

在遠程協作、在線教學、監控等場景中(當然啦!還有其他的用途,這裏就不說了,懂得都懂),屏幕共享是一項非常重要的技術。本文將介紹如何使用 Golang 開發一個基於 WebSocket 的屏幕共享系統,實現遠程查看電腦屏幕的功能。

技術原理

整個屏幕共享的流程如下:

  1. 定時截圖:使用kbinani/screenshot 進行屏幕捕獲,每隔 100ms 採集一次屏幕。

  2. 圖片壓縮:爲了減少數據傳輸量,將截圖壓縮爲 JPEG 格式。

  3. WebSocket 傳輸:通過gorilla/websocket實現 WebSocket 服務器,將截圖數據推送給瀏覽器客戶端。

  4. 前端展示:瀏覽器通過WebSocket接收圖像數據,並動態更新img標籤以實時顯示共享的屏幕內容。

後端實現

我們首先創建一個 go 項目並使用 go 編寫一個 WebSocket 服務器,用於捕獲屏幕並實時發送給客戶端,具體操作如下所示:

mkdir websocket-demo
cd websocket-demo/ && go mod init websocket-demo
# 安裝 WebSocket 庫
go get -u github.com/gorilla/websocket
# 安裝屏幕截圖庫
go get -u github.com/kbinani/screenshot

然後鍵入如下代碼,具體如下所示:

package main
import (
	"bytes"
	"fmt"
	"image/jpeg"
	"net/http"
	"time"
	"github.com/gorilla/websocket"
	"github.com/kbinani/screenshot"
)
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool { return true }, // 允許跨域
}
// 捕獲屏幕並轉換爲JPEG
func captureScreen() ([]byte, error) {
	img, err := screenshot.CaptureDisplay(0) // 僅截取主屏幕
	if err != nil {
		return nil, err
	}
	buf := new(bytes.Buffer)
	jpeg.Encode(buf, img, &jpeg.Options{Quality: 50}) // 50% 質量壓縮
	return buf.Bytes(), nil
}
// 處理WebSocket連接
func handleWS(conn *websocket.Conn) {
	defer conn.Close()
	for {
		time.Sleep(100 * time.Millisecond) // 每100ms發送一次(10FPS)
		imgData, err := captureScreen()
		if err != nil {
			fmt.Println("截圖失敗:", err)
			continue
		}
		// 發送圖片數據
		if err = conn.WriteMessage(websocket.BinaryMessage, imgData); err != nil {
			fmt.Println("發送失敗:", err)
			break
		}
	}
}
func main() {
	http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
		conn, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			fmt.Println("WebSocket連接失敗:", err)
			return
		}
		go handleWS(conn) // 處理WebSocket連接
	})
	fmt.Println("WebSocket 服務器啓動,訪問 ws://localhost:9527/ws")
	http.ListenAndServe(":9527", nil)
}

代碼解析

⚠️注意: 需要提前安裝好 opencv 相關依賴

前端實現

前端需要使用 WebSocket 接收屏幕圖像數據,並動態更新img標籤,具體事項如下所示:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>屏幕共享</title>
</head>
<body>
    <h2>實時屏幕共享</h2>
    <img id="screen" style="border: 1px solid black; width: 80%; max-width: 1024px;">
    <script>
        let ws = new WebSocket("ws://localhost:9527/ws");
        let img = document.getElementById("screen");
        ws.binaryType = "blob";
        ws.onmessage = function (event) {
            let url = URL.createObjectURL(event.data);
            img.src = url;
        };
        ws.onclose = function () {
            alert("連接已斷開");
        };
    </script>
</body>
</html>

代碼解析

運行項目效果

我們分別先運行 go 後端代碼,再打開 html 文件,具體效果展示如下圖所示:

⚠️注意:請忽略我運行中出現的錯誤信息,這個是 opencv 的依賴報錯告警,不影響運行,在你的電腦運行的話可能不會出現,只要設置好 opencv 的環境就不會出現了。

前端運行效果圖如下所示:

總結

本方案適用於局域網屏幕共享、遠程桌面監控、在線教學等,如果需要更流暢的視頻流,可以結合 FFmpeg + WebRTC/RTMP 實現更高級的屏幕共享。今天的內容就到此結束了,感謝您的收看,歡迎關注本公衆號!🚀🚀🚀 最後歡迎您的三連!!!🌹🌹🌹

請在微信客戶端打開

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/G8-alfUG8Vo7vdRCOUQgyg