Maison  >  Article  >  développement back-end  >  go-zero+WebRTC réalise une communication vidéo en temps réel

go-zero+WebRTC réalise une communication vidéo en temps réel

WBOY
WBOYoriginal
2023-06-22 15:53:082132parcourir

Avec le développement de la technologie de communication vidéo, de plus en plus de scénarios d'application nécessitent des fonctions de communication vidéo en temps réel. WebRTC est un projet open source qui permet aux navigateurs et aux applications mobiles de communiquer en temps réel, et go-zero est un cadre permettant de créer rapidement des services Web en langage Go hautes performances. Cet article explique comment utiliser go-zero et WebRTC pour mettre en œuvre une communication vidéo en temps réel.

1. Compréhension préliminaire de WebRTC

WebRTC est un projet open source de Google qui permet une communication en temps réel entre les navigateurs et les applications mobiles. Il fournit des fonctions de communication audio et vidéo en temps réel. WebRTC utilise une série de technologies pour réaliser des fonctions de communication en temps réel, notamment :

  1. Protocole de transmission TCP/UDP
  2. Technologie ICE (Interactive Connectivity establishment) pour déterminer le chemin optimal et le protocole de transmission correct
  3. SDP (Session Description Protocol ), utilisé pour décrire le déroulement d'une session
  4. Protocole STUN (Session Traversal Utilities for NAT), utilisé pour détecter et contourner le NAT
  5. Protocole TURN (Traversal Using Relays around NAT), utilisé pour échouer la connexion en utilisant STUN aux deux extrémités Lors de la transmission, utilisez un serveur relais pour la transmission

2. Compréhension préliminaire de go-zero

go-zero est un cadre permettant de créer rapidement des services Web en langage Go hautes performances. Il présente les caractéristiques suivantes :

  1. Basé sur le framework RPC, prend en charge plusieurs protocoles
  2. Hautes performances, utilise la technologie Sync.Pool et pool de mémoire
  3. Plug-in, extension flexible
  4. Prend en charge le middleware
  5. Prend en charge la passerelle API

3. Utilisez go-zero et WebRTC pour réaliser une communication vidéo en temps réel

Afin d'utiliser go-zero et WebRTC pour réaliser une communication vidéo en temps réel, nous devons suivre les étapes suivantes :

  1. Créer le Web de go-zero service
  2. Implémenter la signalisation WebRTC Le serveur
  3. implémente la transmission en streaming vidéo de WebRTC
  4. implémente la page frontale

Le serveur de signalisation est un élément clé de WebRTC et est utilisé pour établir et maintenir le canal de communication vidéo. Nous pouvons utiliser go-zero pour implémenter le serveur de signalisation. Tout d'abord, nous devons importer le package de dépendances go-zero approprié, comme indiqué ci-dessous :

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"
)

Ensuite, nous pouvons implémenter le serveur de protocole WebSocket et le gestionnaire de routage correspondant. La fonction principale du gestionnaire de routage est de gérer les connexions Websocket et la transmission de données, et de mettre en œuvre les fonctions de base du serveur de signalisation. Le code est le suivant :

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)
}

Dans le code ci-dessus, nous traitons les demandes de connexion WebSocket via la fonction websocket.Handler, où la fonction createHub est utilisée pour créer une structure hub représentant le serveur de signaux. La fonction handleWebSocket est utilisée pour gérer les opérations de lecture et d'écriture des connexions Websocket. La fonction handleMessage est utilisée pour gérer différents types de messages de signalisation. Dans le même temps, afin de maintenir les connexions entre les différents clients, nous avons créé une structure de hub et utilisé des pipelines tels que l'enregistrement, la désinscription et la diffusion pour maintenir la liste des clients et répondre lorsque le client se connecte, se déconnecte et envoie des messages.

Ensuite, nous devons implémenter la fonction de streaming vidéo de WebRTC. Dans WebRTC, les flux vidéo sont transmis via des objets PeerConnection. Nous pouvons générer un message de signalisation d'offre et l'envoyer à un autre homologue en appelant la méthode CreateOffer de RTCPeerConnection. Après avoir traité le message d'offre, un autre homologue peut appeler la méthode CreateAnswer de RTCPeerConnection, générer un message de réponse et le renvoyer. Finalement, les deux parties enverront leurs informations de description SDP à l'autre partie via les méthodes SetLocalDescription et SetRemoteDescription de RTCPeerConnection pour établir un canal de communication vidéo. Le code est le suivant :

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
}

Dans le code ci-dessus, nous définissons trois méthodes de traitement : generateOffer, handleOffer et handleAnswer. generateOffer est utilisé pour générer un message de signalisation d'offre et renvoyer un objet de type sdp.SessionDescription. handleOffer et handleAnswer sont utilisés respectivement pour traiter les messages de signalisation d'offre et de réponse et définir leurs informations de description SDP respectives via les méthodes SetRemoteDescription et SetLocalDescription.

Enfin, nous devons implémenter la page frontale et implémenter la fonction de streaming vidéo via WebRTC. Je n’entrerai pas dans les détails ici.

Résumé

Cet article présente comment utiliser go-zero et WebRTC pour mettre en œuvre une communication vidéo en temps réel. Nous avons d'abord présenté les connaissances de base de WebRTC, puis utilisé go-zero pour implémenter les fonctions de serveur de signalisation et de streaming vidéo de WebRTC, et enfin implémenté la page frontale. Grâce aux pratiques ci-dessus, nous avons non seulement acquis une compréhension approfondie de la technologie de base de WebRTC, mais nous avons également appris à utiliser go-zero pour le développement rapide de services Web.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn