>  기사  >  백엔드 개발  >  go-zero+WebRTC는 실시간 영상통신을 실현합니다

go-zero+WebRTC는 실시간 영상통신을 실현합니다

WBOY
WBOY원래의
2023-06-22 15:53:082131검색

영상 통신 기술이 발전함에 따라 점점 더 많은 응용 시나리오에 실시간 영상 통신 기능이 필요합니다. WebRTC는 브라우저와 모바일 애플리케이션이 실시간으로 통신할 수 있도록 하는 오픈소스 프로젝트이며, go-zero는 고성능 Go 언어 웹 서비스를 빠르게 구축하기 위한 프레임워크입니다. 이 기사에서는 go-zero 및 WebRTC를 사용하여 실시간 비디오 통신을 구현하는 방법을 소개합니다.

1. WebRTC에 대한 사전 이해

WebRTC는 브라우저와 모바일 애플리케이션 간의 실시간 통신을 가능하게 하는 Google 오픈소스 프로젝트로, 실시간 오디오 및 비디오 통신과 데이터 전송 기능을 제공합니다. WebRTC는 일련의 기술을 사용하여 실시간 통신 기능을 구현합니다.

  1. TCP/UDP 전송 프로토콜
  2. ICE(Interactive Connectivity Deployment) 기술을 통해 최적의 경로와 올바른 전송 프로토콜을 결정
  3. SDP(Session Description Protocol) ) 프로토콜, 세션이 어떻게 진행되는지 설명하는 데 사용됨
  4. STUN(Session Traversal Utilities for NAT) 프로토콜, NAT를 감지하고 우회하는 데 사용됨
  5. TURN(Traversal Using Relays around NAT) 프로토콜, 양쪽 끝에서 STUN을 사용하여 연결에 실패하는 데 사용됨 전송시에는 중계서버를 이용하여 전송합니다

2. 고제로에 대한 사전 이해

go-zero는 고성능 Go언어 웹서비스를 빠르게 구축하기 위한 프레임워크입니다. 다음과 같은 특징을 가지고 있습니다:

  1. RPC 프레임워크 기반, 다양한 프로토콜 지원
  2. 고성능, Sync.Pool 및 메모리 풀 기술 사용
  3. 플러그인, 유연한 확장
  4. 미들웨어 지원
  5. API 게이트웨이 지원

3. go-zero와 WebRTC를 사용하여 실시간 영상 통신을 구현합니다

go-zero와 WebRTC를 사용하여 실시간 영상 통신을 구현하려면 다음 단계를 완료해야 합니다.

  1. go-zero의 웹 구축 service
  2. WebRTC 시그널링 구현 서버
  3. 는 WebRTC의 비디오 스트리밍 전송
  4. 을 구현하고 프런트 엔드 페이지

을 구현합니다. 시그널링 서버는 WebRTC의 핵심 부분이며 비디오 통신 채널을 설정하고 유지하는 데 사용됩니다. go-zero를 사용하여 신호 서버를 구현할 수 있습니다. 먼저 아래와 같이 관련 go-zero 종속성 패키지를 가져와야 합니다.

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 프로토콜 서버와 해당 라우팅 핸들러를 구현할 수 있습니다. 라우팅 핸들러의 주요 기능은 웹소켓 연결과 데이터 전송을 처리하고 시그널링 서버의 기본 기능을 구현하는 것입니다. 코드는 다음과 같습니다.

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 함수는 웹소켓 연결의 읽기 및 쓰기 작업을 처리하는 데 사용됩니다. handlerMessage 함수는 다양한 유형의 신호 메시지를 처리하는 데 사용됩니다. 동시에 서로 다른 클라이언트 간의 연결을 유지하기 위해 허브 구조를 만들고 등록, 등록 취소, 브로드캐스트 등의 파이프를 사용하여 클라이언트 목록을 유지하고 클라이언트가 연결, 연결 끊기 및 메시지 처리를 보낼 때 응답합니다.

다음으로 WebRTC의 비디오 스트리밍 기능을 구현해야 합니다. WebRTC에서 비디오 스트림은 PeerConnection 객체를 통해 전송됩니다. RTCPeerConnection의 CreateOffer 메소드를 호출하여 제안 신호 메시지를 생성하고 이를 다른 피어에게 보낼 수 있습니다. 제안 메시지를 처리한 후 다른 Peer는 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, handlerOffer 및 handlerAnswer의 세 가지 처리 방법을 정의합니다. generateOffer는 제안 신호 메시지를 생성하고 sdp.SessionDescription 유형의 객체를 반환하는 데 사용됩니다. handlerOffer 및 handlerAnswer는 각각 제안 및 응답 신호 메시지를 처리하는 데 사용되며 SetRemoteDescription 및 SetLocalDescription 메서드를 통해 해당 SDP 설명 정보를 설정합니다.

마지막으로 WebRTC를 통해 프런트 엔드 페이지를 구현하고 비디오 스트리밍 기능을 구현해야 합니다. 여기서는 자세히 설명하지 않겠습니다.

요약

이 글에서는 go-zero와 WebRTC를 활용하여 실시간 영상통신을 구현하는 방법을 소개합니다. 먼저 WebRTC에 대한 기본 지식을 소개한 후 go-zero를 사용하여 WebRTC의 시그널링 서버 및 비디오 스트리밍 기능을 구현하고 마지막으로 프런트 엔드 페이지를 구현했습니다. 위의 실습을 통해 우리는 WebRTC의 핵심 기술에 대한 심층적인 이해를 얻었을 뿐만 아니라, 신속한 웹 서비스 개발을 위해 go-zero를 활용하는 방법도 배웠습니다.

위 내용은 go-zero+WebRTC는 실시간 영상통신을 실현합니다의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.