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:
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:
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:
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!