Rumah  >  Artikel  >  pembangunan bahagian belakang  >  go-zero+WebRTC merealisasikan komunikasi video masa nyata

go-zero+WebRTC merealisasikan komunikasi video masa nyata

WBOY
WBOYasal
2023-06-22 15:53:082132semak imbas

Dengan perkembangan teknologi komunikasi video, semakin banyak senario aplikasi memerlukan fungsi komunikasi video masa nyata. WebRTC ialah projek sumber terbuka yang membolehkan penyemak imbas dan aplikasi mudah alih berkomunikasi dalam masa nyata, dan go-zero ialah rangka kerja untuk membina perkhidmatan web bahasa Go berprestasi tinggi dengan cepat. Artikel ini akan memperkenalkan cara menggunakan go-zero dan WebRTC untuk melaksanakan komunikasi video masa nyata.

1. Pemahaman awal tentang WebRTC

WebRTC ialah projek sumber terbuka Google yang membolehkan komunikasi masa nyata antara penyemak imbas dan aplikasi mudah alih Ia menyediakan komunikasi audio dan video masa nyata dan fungsi penghantaran data . WebRTC menggunakan satu siri teknologi untuk mencapai fungsi komunikasi masa nyata, termasuk:

  1. TCP/UDP Transport Protocol
  2. teknologi ICE (Interactive Connectivity Establishment) untuk menentukan laluan optimum dan betul Protokol pengangkutan
  3. Protokol SDP (Session Description Protocol), digunakan untuk menerangkan cara sesi berlangsung
  4. protokol STUN (Session Traversal Utilities for NAT), digunakan untuk mengesan dan memintas NAT
  5. Protokol TURN (Traversal Using Relays around NAT) digunakan untuk menggunakan pelayan geganti untuk penghantaran apabila kedua-dua hujung tidak dapat disambungkan menggunakan STUN

2 Pemahaman awal tentang go-zero

go-. sifar ialah rangka kerja untuk membina perkhidmatan web bahasa Go berprestasi tinggi dengan cepat. Ia mempunyai ciri-ciri berikut:

  1. Berdasarkan rangka kerja RPC, menyokong berbilang protokol
  2. Prestasi tinggi, menggunakan Sync.Pool dan teknologi kolam memori
  3. Palam masuk, Sambungan fleksibel
  4. Sokong middleware
  5. Sokongan get laluan API

3 Gunakan go-zero dan WebRTC untuk melaksanakan komunikasi video masa nyata

Dalam. untuk menggunakan go- Untuk mencapai komunikasi video masa nyata antara sifar dan WebRTC, kita perlu melengkapkan langkah berikut:

  1. Membina perkhidmatan Web go-zero
  2. Melaksanakan isyarat pelayan WebRTC
  3. Pelaksanaan penstriman video WebRTC
  4. melaksanakan halaman hujung hadapan

Pelayan isyarat ialah bahagian penting WebRTC dan digunakan untuk mewujudkan dan mengekalkan saluran komunikasi video. Kita boleh menggunakan go-zero untuk melaksanakan pelayan isyarat. Mula-mula, kita perlu mengimport pakej pergantungan go-zero yang berkaitan, seperti yang ditunjukkan di bawah:

import (
    "bytes"
    "encoding/json"
    "github.com/creasty/defaults"
    "github.com/go-chi/chi/v5"
    "github.com/gorilla/websocket"
    "github.com/rs/zerolog"
    "github.com/rs/zerolog/log"
    "github.com/segmentio/ksuid"
    "math/rand"
    "net/http"
    "sync"
    "time"
)

Seterusnya, kita boleh melaksanakan pelayan protokol WebSocket dan pengendali penghalaan yang sepadan. Fungsi utama pengendali penghalaan adalah untuk mengendalikan sambungan soket web dan penghantaran data, dan melaksanakan fungsi asas pelayan isyarat. Kodnya adalah seperti berikut:

type SignalServer struct {
    hub *Hub
    mu  sync.Mutex
}

func NewSignalServer() *SignalServer {
    return &SignalServer{
        hub: newHub(),
    }
}

func (s *SignalServer) routes() *chi.Mux {
    r := chi.NewRouter()
    r.Handle("/ws", websocket.Handler(s.handleWebSocket))
    return r
}

func (s *SignalServer) handleWebSocket(conn *websocket.Conn) {
    sessionId := ksuid.New().String()
    client := &Client{
        id:   sessionId,
        conn: conn,
        send: make(chan []byte, 256),
        hub:  s.hub,
    }
    s.hub.register <- client
    go client.writePump()

    for {
        _, message, err := conn.ReadMessage()
        if err != nil {
            break
        }
        s.handleMessage(client, message)
    }

    s.hub.unregister <- client
    conn.Close()
}

func (s *SignalServer) handleMessage(client *Client, data []byte) {
    log.Debug().Msgf("received message: %s", data)
    message := &SignalingMessage{}
    if err := json.Unmarshal(data, message); err != nil {
        log.Error().Msgf("failed to unmarshal data: %s", err.Error())
        return
    }

    switch message.Type {
    case "register":
        s.handleRegister(client, message)
    case "offer":
        s.hub.broadcast <- &MessageData{
            SenderId: client.id,
            Type:     "offer",
            Payload:  message.Payload,
        }
    case "answer":
        s.hub.broadcast <- &MessageData{
            SenderId: client.id,
            Type:     "answer",
            Payload:  message.Payload,
        }
    case "candidate":
        s.hub.broadcast <- &MessageData{
            SenderId: client.id,
            Type:     "candidate",
            Payload:  message.Payload,
        }
    default:
        log.Error().Msgf("unknown message type: %s", message.Type)
    }
}

func (s *SignalServer) handleRegister(client *Client, message *SignalingMessage) {
    room := message.Payload
    s.mu.Lock()
    defer s.mu.Unlock()
    if _, ok := s.hub.rooms[room]; !ok {
        s.hub.rooms[room] = make(map[string]*Client)
    }
    s.hub.rooms[room][client.id] = client
    log.Debug().Msgf("client %s registered in room %s", client.id, room)
}

Dalam kod di atas, kami mengendalikan permintaan sambungan WebSocket melalui fungsi websocket.Handler, di mana fungsi createHub digunakan untuk mencipta struktur hab yang mewakili pelayan isyarat. Fungsi handleWebSocket digunakan untuk mengendalikan operasi baca dan tulis sambungan soket web. Fungsi handleMessage digunakan untuk mengendalikan pelbagai jenis mesej isyarat. Pada masa yang sama, untuk mengekalkan hubungan antara pelanggan yang berbeza, kami mencipta struktur hab dan menggunakan saluran paip seperti mendaftar, menyahdaftar dan menyiarkan untuk mengekalkan senarai pelanggan dan bertindak balas apabila pelanggan menyambung, memutuskan sambungan dan menghantar mesej.

Seterusnya, kita perlu melaksanakan fungsi penstriman video WebRTC. Dalam WebRTC, strim video dihantar melalui objek PeerConnection. Kami boleh menjana mesej isyarat tawaran dan menghantarnya kepada Peer lain dengan menghubungi kaedah CreateOffer RTCPeerConnection. Selepas memproses mesej tawaran, Peer lain boleh memanggil kaedah CreateAnswer RTCPeerConnection, menjana mesej jawapan dan menghantarnya semula. Akhirnya, kedua-dua pihak akan menghantar maklumat penerangan SDP mereka kepada pihak lain melalui kaedah SetLocalDescription dan SetRemoteDescription RTCPeerConnection untuk mewujudkan saluran komunikasi video. Kodnya adalah seperti berikut:

func (p *Peer) generateOffer() (*sdp.SessionDescription, error) {
    offer, err := p.pconn.CreateOffer(nil)
    if err != nil {
        return nil, err
    }

    if err := p.pconn.SetLocalDescription(offer); err != nil {
        return nil, err
    }

    return offer, nil
}

func (p *Peer) handleOffer(payload string) (*sdp.SessionDescription, error) {
    offer, err := webrtc.NewSessionDescription(sdp.SessionDescriptionProtocolType, payload)
    if err != nil {
        return nil, err
    }
    if err := p.pconn.SetRemoteDescription(offer); err != nil {
        return nil, err
    }

    answer, err := p.pconn.CreateAnswer(nil)
    if err != nil {
        return nil, err
    }

    if err := p.pconn.SetLocalDescription(answer); err != nil {
        return nil, err
    }

    return answer, nil
}

func (p *Peer) handleAnswer(payload string) error {
    answer, err := webrtc.NewSessionDescription(sdp.SessionDescriptionProtocolType, payload)
    if err != nil {
        return err
    }
    if err := p.pconn.SetRemoteDescription(answer); err != nil {
        return err
    }
    return nil
}

Dalam kod di atas, kami mentakrifkan tiga kaedah pemprosesan: generateOffer, handleOffer dan handleAnswer. generateOffer digunakan untuk menjana mesej isyarat tawaran dan mengembalikan objek jenis sdp.SessionDescription. handleOffer dan handleAnswer digunakan untuk memproses tawaran dan menjawab mesej isyarat masing-masing, dan menetapkan maklumat penerangan SDP masing-masing melalui kaedah SetRemoteDescription dan SetLocalDescription.

Akhir sekali, kami perlu melaksanakan halaman hujung hadapan dan melaksanakan fungsi penstriman video melalui WebRTC. Saya tidak akan pergi ke butiran di sini.

Ringkasan

Artikel ini memperkenalkan cara menggunakan go-zero dan WebRTC untuk melaksanakan komunikasi video masa nyata. Kami mula-mula memperkenalkan pengetahuan asas WebRTC, kemudian menggunakan go-zero untuk melaksanakan pelayan isyarat dan fungsi penstriman video WebRTC, dan akhirnya melaksanakan halaman hadapan. Melalui amalan di atas, kami bukan sahaja mendapat pemahaman yang mendalam tentang teknologi teras WebRTC, tetapi juga mempelajari cara menggunakan go-zero untuk pembangunan perkhidmatan Web yang pantas.

Atas ialah kandungan terperinci go-zero+WebRTC merealisasikan komunikasi video masa nyata. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn