ビデオ通信技術の発展に伴い、リアルタイムビデオ通信機能の実装を必要とするアプリケーションシナリオがますます増えています。 WebRTC は、ブラウザーとモバイル アプリケーションがリアルタイムで通信できるようにするオープン ソース プロジェクトであり、go-zero は、高パフォーマンスの Go 言語 Web サービスを迅速に構築するためのフレームワークです。この記事では、go-zeroとWebRTCを使ってリアルタイムビデオコミュニケーションを実現する方法を紹介します。
1. WebRTC の事前理解
WebRTC は、ブラウザとモバイル アプリケーション間のリアルタイム通信を可能にする Google のオープンソース プロジェクトであり、リアルタイムの音声およびビデオ通信とデータ送信機能を提供します。 。 WebRTC は、次のような一連のテクノロジーを使用してリアルタイム通信機能を実現します。
2 を使用して両端が接続できない場合に、送信にリレー サーバーを使用するために使用されます。
go-zero は、高パフォーマンスの Go 言語 Web サービスを迅速に構築するためのフレームワークです。次の特徴があります: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" )次に、WebSocket プロトコル サーバーと対応するルーティング ハンドラーを実装できます。ルーティング ハンドラーの主な機能は、WebSocket 接続とデータ送信を処理し、シグナリング サーバーの基本機能を実装することです。コードは次のとおりです。
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) }上記のコードでは、websocket.Handler 関数を使用して WebSocket 接続リクエストを処理します。ここで、createHub 関数を使用してシグナル サーバーを表すハブ構造を作成します。 handleWebSocket 関数は、WebSocket 接続の読み取りおよび書き込み操作を処理するために使用されます。 handleMessage 関数は、さまざまな種類のシグナリング メッセージを処理するために使用されます。同時に、異なるクライアント間の接続を維持するために、ハブ構造を作成し、register、unregister、broadcast などのパイプを使用してクライアント リストを維持し、クライアントが接続、切断、メッセージを送信するときに応答します。 次に、WebRTC のビデオ ストリーミング機能を実装する必要があります。 WebRTC では、ビデオ ストリームは PeerConnection オブジェクトを通じて送信されます。 RTCPeerConnection の CreateOffer メソッドを呼び出すことで、オファー シグナリング メッセージを生成し、別のピアに送信できます。オファー メッセージを処理した後、別のピアは RTCPeerConnection の CreateAnswer メソッドを呼び出し、応答メッセージを生成して送り返すことができます。最終的に、両当事者は、RTCPeerConnection の SetLocalDescription メソッドと SetRemoteDescription メソッドを通じて SDP 記述情報を相手に送信し、ビデオ通信チャネルを確立します。コードは次のとおりです。
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 }上記のコードでは、generateOffer、handleOffer、および handleAnswer という 3 つの処理メソッドを定義します。 generateOffer は、オファー シグナリング メッセージを生成し、sdp.SessionDescription 型のオブジェクトを返すために使用されます。 handleOffer と handleAnswer は、それぞれオファー シグナリング メッセージとアンサー シグナリング メッセージを処理するために使用され、SetRemoteDescription メソッドと SetLocalDescription メソッドを通じてそれぞれの SDP 記述情報を設定します。 最後に、フロントエンド ページを実装し、WebRTC を介したビデオ ストリーミング機能を実装する必要があります。ここでは詳細には触れません。 概要 この記事では、go-zero と WebRTC を使用してリアルタイム ビデオ コミュニケーションを実装する方法を紹介します。最初に WebRTC の基礎知識を紹介し、次に go-zero を使用して WebRTC のシグナリング サーバーとビデオ ストリーミング機能を実装し、最後にフロントエンド ページを実装しました。上記の実践を通じて、WebRTC のコア技術を深く理解しただけでなく、迅速な Web サービス開発のための go-zero の使用方法も学びました。
以上がgo-zero+WebRTCでリアルタイムビデオコミュニケーションを実現の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。