ビデオ通信技術の発展に伴い、リアルタイムビデオ通信機能の実装を必要とするアプリケーションシナリオがますます増えています。 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" )
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) }
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 }
以上がgo-zero+WebRTCでリアルタイムビデオコミュニケーションを実現の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。