README

go-webrtc

Build Status

WebRTC for Golang.

Current Status:

As of October 2019, this repository is not actively maintained. The project for which it was developed is now using pion/webrtc instead.

Usage

To immediately see some action, try the chat demo from two machines (or one...)

  • git clone https://github.com/keroserene/go-webrtc
  • cd go-webrtc
  • go run demo/chat/chat.go

Type "start" in one of the Peers, and copy the session descriptions. (This is the "copy-paste" signalling channel). If ICE negotiation succeeds, a really janky chat session should begin.

To write Go code which requires WebRTC functionality:

import "github.com/keroserene/go-webrtc/"

And then you can do things like webrtc.NewPeerConnection(...).

If you've never used WebRTC before, there is already plenty of information online along with javascript examples, but for the Go code here, take a look within demo/* for real usage examples which show how to prepare a PeerConnection and set up the necessary callbacks and signaling.

Also, here are the GoDocs.

Dependencies:
  • GCC 5+
  • TODO:
Package naming

The package name is webrtc, even though the repo name is go-webrtc. (This may be slightly contrary to Go convention, unless we consider the suffix to really begin at the last dash. Reasons:

  • Dashes aren't allowed in package names
  • Including the word "go" in a Go package name seems redundant
  • Just calling this repo webrtc wouldn't make sense either.
  • Also you can rename imported packages to whatever you like.

(e.g. import "foo" "github.com/keroserene/go-webrtc")

Building

Latest tested native webrtc archive: 88f5d9180eae78a6162cccd78850ff416eb82483

There are currently two ways to build gowebrtc: the easy way, and the hard way.

The hard way is to build from scratch, which involves Google's depot_tools and chromium stuff, gclient syncing, which takes a couple hours, and possibly many more if you run into problems... along with writing a custom ninja file and concatenating archives correctly and such.

See webrtc.org native-code dev.

The easy way is to use the pre-built archive I've provided in lib/.

Once the archive is ready, cgo takes care of everything, and building is as easy as go build or go install.

TODO(keroserene): More information / provide a real build script to automate the hard way so it becomes the easy way. (See Issue #23)

Expand ▾ Collapse ▴

Documentation

Overview

    Package webrtc/data contains the go wrapper for the Peer-to-Peer Data API portion of WebRTC spec.

    See: https://w3c.github.io/webrtc-pc/#idl-def-RTCDataChannel

    Package webrtc is a golang wrapper on native code WebRTC.

    For consistency with the browser-based WebRTCs, the interface here is based loosely on: w3c.github.io/webrtc-pc

    The main goal of this project is to present a golang WebRTC package in the most idiomatic and simple-to-use way.

    However, to provide a better experience for users of this package, there are differences inherent in the interface written here and the original native code WebRTC - from the golang requirement of Capitalized identifiers for public interfaces, to the replacement of certain callbacks with goroutines.

    Note that building the necessary libwebrtc static library is excessively complicated, which is why the necessary platform-specific archives will be provided in lib/. This also mitigates the possibility that future commits on native libwebrtc will break go-webrtc, because the interface with the native code, through the intermediate CGO layer, is relatively fragile.

    Due to other external goals of the developers, this package will only be focused on DataChannels. However, extending this package to allow video/audio media streams and related functionality, to be a "complete" WebRTC suite, is entirely possible and will likely happen in the long term. (Issue #7) This will however have implications for the archives that need to be built and linked.

    Please share any improvements or concerns as issues or pull requests on github.

    Index

    Constants

    This section is empty.

    Variables

    View Source
    var (
    	INFO  *log.Logger
    	WARN  *log.Logger
    	ERROR *log.Logger
    	TRACE *log.Logger
    )
    View Source
    var DCMap = NewCGOMap()
    View Source
    var PCMap = NewCGOMap()
    View Source
    var SdpTypes = []string{"offer", "pranswer", "answer", "rollback"}

      TODO: Turn into Enum.

      Functions

      func CgoSdpToGoString

      func CgoSdpToGoString(sdp C.CGO_sdp) string

      func EnumToStringSafe

      func EnumToStringSafe(value int, valueStrings []string) string

        Return a string value for an integer enum from a mapping array or the integer string if the integer it outside the expected range.

        func MaxPacketLifeTime

        func MaxPacketLifeTime(maxPacketLifeTime int) func(*DataChannelInit)

          MaxPacketLifeTime configures a DataChannels 'maxRetransmitTime' option.

          func MaxRetransmits

          func MaxRetransmits(maxRetransmits int) func(*DataChannelInit)

            MaxRetransmits configures a DataChannels 'maxRetransmits' option.

            func Negotiated

            func Negotiated(negotiated bool) func(*DataChannelInit)

              Negotiated configures a DataChannels 'negotiated' option.

              func Ordered

              func Ordered(ordered bool) func(*DataChannelInit)

                Ordered configures a DataChannels 'ordered' option.

                func SetLoggingVerbosity

                func SetLoggingVerbosity(level int)

                  Logging verbosity level, from 0 (nothing) upwards.

                  Types

                  type BundlePolicy

                  type BundlePolicy int
                  const (
                  	BundlePolicyBalanced BundlePolicy = iota
                  	BundlePolicyMaxBundle
                  	BundlePolicyMaxCompat
                  )

                    These "Enum" consts must match order in: peerconnectioninterface.h There doesn't seem to be a way to have a named container for enums in go, and the idiomatic way seems to be just prefixes.

                    func (BundlePolicy) String

                    func (p BundlePolicy) String() string

                    type CGOMap

                    type CGOMap struct {
                    	// contains filtered or unexported fields
                    }

                    func NewCGOMap

                    func NewCGOMap() CGOMap

                    func (*CGOMap) Delete

                    func (m *CGOMap) Delete(index int)

                    func (*CGOMap) Get

                    func (m *CGOMap) Get(index int) interface{}

                    func (*CGOMap) Set

                    func (m *CGOMap) Set(p interface{}) int

                    type Configuration

                    type Configuration struct {
                    	IceServers []IceServer
                    	IceTransportPolicy
                    	BundlePolicy
                    	// [ED] RtcpMuxPolicy        RtcpMuxPolicy
                    	PeerIdentity string // Target peer identity
                    
                    }

                    func NewConfiguration

                    func NewConfiguration(options ...ConfigurationOption) *Configuration

                      Create a new Configuration with default values according to spec. Accepts any number of |IceServer|s. Returns nil if there's an error.

                      func (*Configuration) AddIceServer

                      func (config *Configuration) AddIceServer(params ...string) error

                      type ConfigurationOption

                      type ConfigurationOption func(c *Configuration) error

                        Used in Configuration's variadic functional constructor

                        func OptionBundlePolicy

                        func OptionBundlePolicy(policy BundlePolicy) ConfigurationOption

                        func OptionIceServer

                        func OptionIceServer(params ...string) ConfigurationOption

                        func OptionIceTransportPolicy

                        func OptionIceTransportPolicy(policy IceTransportPolicy) ConfigurationOption

                        type DataChannel

                        type DataChannel struct {
                        	BufferedAmountLowThreshold int
                        	BinaryType                 string
                        
                        	// Event Handlers
                        	OnOpen              func()
                        	OnClose             func()
                        	OnMessage           func([]byte) // byte slice.
                        	OnBufferedAmountLow func()
                        	// contains filtered or unexported fields
                        }
                          DataChannel
                          

                          OnError - is not implemented because the underlying Send always returns true as specified for SCTP, there is no reasonable exposure of other specific errors from the native code, and OnClose already covers the bases.

                          func NewDataChannel

                          func NewDataChannel(o unsafe.Pointer) *DataChannel

                            Create a Go Channel struct, and prepare internal CGO references / observers. The most reasonable place for this to be created is from PeerConnection, which is not available in the subpackage.

                            func (*DataChannel) BufferedAmount

                            func (c *DataChannel) BufferedAmount() int

                            func (*DataChannel) Close

                            func (c *DataChannel) Close() error

                            func (*DataChannel) ID

                            func (c *DataChannel) ID() int

                            func (*DataChannel) Label

                            func (c *DataChannel) Label() string

                            func (*DataChannel) MaxPacketLifeTime

                            func (c *DataChannel) MaxPacketLifeTime() uint

                            func (*DataChannel) MaxRetransmits

                            func (c *DataChannel) MaxRetransmits() uint

                            func (*DataChannel) Negotiated

                            func (c *DataChannel) Negotiated() bool

                            func (*DataChannel) Ordered

                            func (c *DataChannel) Ordered() bool

                            func (*DataChannel) Protocol

                            func (c *DataChannel) Protocol() string

                            func (*DataChannel) ReadyState

                            func (c *DataChannel) ReadyState() DataState

                            func (*DataChannel) Send

                            func (c *DataChannel) Send(data []byte)

                              Send a message over a DataChannel in binary mode.

                              func (*DataChannel) SendText

                              func (c *DataChannel) SendText(text string)

                                SendText sends a message over the DataChannel in text mode.

                                type DataChannelInit

                                type DataChannelInit struct {
                                	Ordered           bool
                                	MaxPacketLifeTime int
                                	MaxRetransmits    int
                                	Protocol          string
                                	Negotiated        bool
                                	ID                int
                                }

                                type DataState

                                type DataState int
                                const (
                                	DataStateConnecting DataState = iota
                                	DataStateOpen
                                	DataStateClosing
                                	DataStateClosed
                                )

                                func (DataState) String

                                func (s DataState) String() string

                                type IceCandidate

                                type IceCandidate struct {
                                	Candidate     string `json:"candidate"`
                                	SdpMid        string `json:"sdpMid"`
                                	SdpMLineIndex int    `json:"sdpMLineIndex"`
                                }

                                func DeserializeIceCandidate

                                func DeserializeIceCandidate(msg string) *IceCandidate

                                  Deserialize a received json string into an IceCandidate, if possible.

                                  func (*IceCandidate) Serialize

                                  func (candidate *IceCandidate) Serialize() string

                                    Serialize an IceCandidate into a JSON string.

                                    type IceCandidateType

                                    type IceCandidateType int
                                    const (
                                    	IceCandidateTypeHost IceCandidateType = iota
                                    	IceCandidateTypeSrflx
                                    	IceCandidateTypePrflx
                                    	IceCandidateTypeRelay
                                    )

                                    func (IceCandidateType) String

                                    func (t IceCandidateType) String() string

                                    type IceConnectionState

                                    type IceConnectionState int
                                    const (
                                    	IceConnectionStateNew IceConnectionState = iota
                                    	IceConnectionStateChecking
                                    	IceConnectionStateConnected
                                    	IceConnectionStateCompleted
                                    	IceConnectionStateFailed
                                    	IceConnectionStateDisconnected
                                    	IceConnectionStateClosed
                                    )

                                    func (IceConnectionState) String

                                    func (s IceConnectionState) String() string

                                    type IceCredentialType

                                    type IceCredentialType int

                                    type IceGatheringState

                                    type IceGatheringState int
                                    const (
                                    	IceGatheringStateNew IceGatheringState = iota
                                    	IceGatheringStateGathering
                                    	IceGatheringStateComplete
                                    )

                                    func (IceGatheringState) String

                                    func (s IceGatheringState) String() string

                                    type IceProtocol

                                    type IceProtocol int
                                    const (
                                    	IceProtocolUPD IceProtocol = iota
                                    	IceProtocolTCP
                                    )

                                    func (IceProtocol) String

                                    func (p IceProtocol) String() string

                                    type IceServer

                                    type IceServer struct {
                                    	Urls       []string // The only "required" element.
                                    	Username   string
                                    	Credential string
                                    }

                                    func NewIceServer

                                    func NewIceServer(params ...string) (*IceServer, error)

                                      Create a new IceServer object. Expects anywhere from one to three strings, in this order: - comma-separated list of urls. - username - credential TODO: For the ED version, may need to support CredentialType.

                                      type IceTcpCandidateType

                                      type IceTcpCandidateType int
                                      const (
                                      	IceTcpCandidateTypeActive IceTcpCandidateType = iota
                                      	IceTcpCandidateTypePassive
                                      	IceTcpCandidateTypeSo
                                      )

                                      func (IceTcpCandidateType) String

                                      func (t IceTcpCandidateType) String() string

                                      type IceTransportPolicy

                                      type IceTransportPolicy int
                                      const (
                                      	IceTransportPolicyNone IceTransportPolicy = iota
                                      	IceTransportPolicyRelay
                                      
                                      	IceTransportPolicyAll
                                      )

                                      func (IceTransportPolicy) String

                                      func (p IceTransportPolicy) String() string

                                      type PeerConnection

                                      type PeerConnection struct {
                                      
                                      	// Event handlers
                                      	OnNegotiationNeeded        func()
                                      	OnIceCandidate             func(IceCandidate)
                                      	OnIceCandidateError        func()
                                      	OnSignalingStateChange     func(SignalingState)
                                      	OnIceConnectionStateChange func(IceConnectionState)
                                      	OnIceGatheringStateChange  func(IceGatheringState)
                                      	OnConnectionStateChange    func(PeerConnectionState)
                                      	OnDataChannel              func(*DataChannel)
                                      	// contains filtered or unexported fields
                                      }
                                        WebRTC PeerConnection
                                        

                                        This is the main container of WebRTC functionality - from handling the ICE negotiation to setting up Data Channels.

                                        See: https://w3c.github.io/webrtc-pc/#idl-def-RTCPeerConnection

                                        func NewPeerConnection

                                        func NewPeerConnection(config *Configuration) (*PeerConnection, error)
                                          Construct a WebRTC PeerConnection.
                                          

                                          For a successful connection, provide at least one ICE server (stun or turn) in the |Configuration| struct.

                                          func (*PeerConnection) AddIceCandidate

                                          func (pc *PeerConnection) AddIceCandidate(ic IceCandidate) error

                                          func (*PeerConnection) Close

                                          func (pc *PeerConnection) Close() error

                                          func (*PeerConnection) ConnectionState

                                          func (pc *PeerConnection) ConnectionState() PeerConnectionState

                                            readonly connectionState

                                            func (*PeerConnection) CreateAnswer

                                            func (pc *PeerConnection) CreateAnswer() (*SessionDescription, error)

                                              CreateAnswer prepares an SDP "answer" message. This should only happen in response to an offer received and set as the remote description. Once generated, this answer should then be set as the local description and sent back over the signaling channel to the remote peer.

                                              This method is blocking, and should occur within a separate goroutine.

                                              func (*PeerConnection) CreateDataChannel

                                              func (pc *PeerConnection) CreateDataChannel(label string, options ...func(*DataChannelInit)) (
                                              	*DataChannel, error)

                                              func (*PeerConnection) CreateOffer

                                              func (pc *PeerConnection) CreateOffer() (*SessionDescription, error)

                                                CreateOffer prepares an SDP "offer" message, which should be set as the local description, then sent to the remote peer over a signalling channel. This should only be called by the peer initiating the connection.

                                                This method is blocking, and should occur within a separate goroutine.

                                                func (*PeerConnection) DeleteDataChannel

                                                func (pc *PeerConnection) DeleteDataChannel(dc *DataChannel)

                                                func (*PeerConnection) Destroy

                                                func (pc *PeerConnection) Destroy() error

                                                func (*PeerConnection) GetConfiguration

                                                func (pc *PeerConnection) GetConfiguration() Configuration

                                                func (*PeerConnection) IceConnectionState

                                                func (pc *PeerConnection) IceConnectionState() IceConnectionState

                                                  readonly iceconnectionState

                                                  func (*PeerConnection) IceGatheringState

                                                  func (pc *PeerConnection) IceGatheringState() IceGatheringState

                                                    readonly icegatheringstatee

                                                    func (*PeerConnection) LocalDescription

                                                    func (pc *PeerConnection) LocalDescription() (sdp *SessionDescription)

                                                      readonly localDescription

                                                      func (*PeerConnection) RemoteDescription

                                                      func (pc *PeerConnection) RemoteDescription() (sdp *SessionDescription)

                                                        readonly remoteDescription

                                                        func (*PeerConnection) SetConfiguration

                                                        func (pc *PeerConnection) SetConfiguration(config Configuration) error

                                                        func (*PeerConnection) SetLocalDescription

                                                        func (pc *PeerConnection) SetLocalDescription(sdp *SessionDescription) error

                                                          Set a |SessionDescription| as the local description. The description should be generated from the local peer's CreateOffer or CreateAnswer, and not be a description received over the signaling channel.

                                                          func (*PeerConnection) SetRemoteDescription

                                                          func (pc *PeerConnection) SetRemoteDescription(sdp *SessionDescription) error

                                                            Set a |SessionDescription| as the remote description. This description should be one generated by the remote peer's CreateOffer or CreateAnswer, received over the signaling channel, and not a description created locally.

                                                            If the local peer is the answerer, this must be called before CreateAnswer.

                                                            func (*PeerConnection) SignalingState

                                                            func (pc *PeerConnection) SignalingState() SignalingState

                                                              readonly signalingState

                                                              type PeerConnectionState

                                                              type PeerConnectionState int
                                                              const (
                                                              	PeerConnectionStateNew PeerConnectionState = iota
                                                              	PeerConnectionStateConnecting
                                                              	PeerConnectionStateConnected
                                                              	PeerConnectionStateDisconnected
                                                              	PeerConnectionStateFailed
                                                              )

                                                              func (PeerConnectionState) String

                                                              func (s PeerConnectionState) String() string

                                                              type RtcpMuxPolicy

                                                              type RtcpMuxPolicy int

                                                              type SessionDescription

                                                              type SessionDescription struct {
                                                              	Type string `json:"type"`
                                                              	Sdp  string `json:"sdp"`
                                                              }
                                                                WebRTC SessionDescription
                                                                

                                                                See: https://w3c.github.io/webrtc-pc/#idl-def-RTCSessionDescription

                                                                func DeserializeSessionDescription

                                                                func DeserializeSessionDescription(msg string) *SessionDescription

                                                                  Deserialize a received json string into a SessionDescription, if possible.

                                                                  func NewSessionDescription

                                                                  func NewSessionDescription(sdpType string, serializedSDP C.CGO_sdpString) *SessionDescription

                                                                    Construct a SessionDescription object from a valid msg.

                                                                    func (*SessionDescription) GoStringToCgoSdp

                                                                    func (desc *SessionDescription) GoStringToCgoSdp() C.CGO_sdp

                                                                    func (*SessionDescription) Serialize

                                                                    func (desc *SessionDescription) Serialize() string

                                                                      Serialize a SessionDescription into a JSON string.

                                                                      type SignalingState

                                                                      type SignalingState int
                                                                      const (
                                                                      	SignalingStateStable SignalingState = iota
                                                                      	SignalingStateHaveLocalOffer
                                                                      	SignalingStateHaveLocalPrAnswer
                                                                      	SignalingStateHaveRemoteOffer
                                                                      	SignalingStateHaveRemotePrAnswer
                                                                      	SignalingStateClosed
                                                                      )

                                                                      func (SignalingState) String

                                                                      func (s SignalingState) String() string

                                                                      Directories

                                                                      Path Synopsis
                                                                      * Basic webrtc demo, two local clients speaking over go, to show the most basic * usage of webrtc in Go.
                                                                      * Basic webrtc demo, two local clients speaking over go, to show the most basic * usage of webrtc in Go.
                                                                      chat
                                                                      * Webrtc chat demo.
                                                                      * Webrtc chat demo.