Skip to content

Commit

Permalink
Merge pull request #10 from rsharifnasab/main
Browse files Browse the repository at this point in the history
Fix lint issue and improve readme style
  • Loading branch information
1995parham authored Oct 31, 2024
2 parents 9ca2a96 + 0d85f9f commit 1370b26
Show file tree
Hide file tree
Showing 19 changed files with 213 additions and 116 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ jobs:
steps:
- uses: actions/checkout@v2

# - name: Golang ci-lint
# uses: golangci/golangci-lint-action@v2
# with:
# version: latest
# args: --enable-all
- name: Golang ci-lint
uses: golangci/golangci-lint-action@v2
with:
version: latest
args: --enable-all

# test:
# name: Test
Expand Down
30 changes: 30 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
linters:
enable-all: true
disable:
- depguard
- tagliatelle
- nolintlint
- varnamelen
- ireturn
- execinquery
- gomnd
- mnd
- exportloopref
- copyloopvar
- intrange
- gosec
- gocritic
- forcetypeassert
- wrapcheck
- revive
- stylecheck
linters-settings:
cyclop:
max-complexity: 15
package-average: 0.0
skip-tests: true
funlen:
lines: 85
statements: 40
ignore-comments: true
48 changes: 24 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

> WebRTC media servers stress testing tool
## supported media servers
## Supported media servers

- ion-sfu
- janus

## features
## Features

- audio call
- video call
- Audio call
- Video call


## ION-SFU media-server under load
Expand All @@ -29,30 +29,30 @@

- ion-sfu

``` zsh
# update or create manifests
kubectl apply -f ./deployments/k8s/ion-sfu/configmap.yml
kubectl apply -f ./deployments/k8s/ion-sfu/job.yml
``` zsh
# update or create manifests
kubectl apply -f ./deployments/k8s/ion-sfu/configmap.yml
kubectl apply -f ./deployments/k8s/ion-sfu/job.yml

# delete manifests
kubectl delete -f ./deployments/k8s/ion-sfu/configmap.yml
kubectl delete -f ./deployments/k8s/ion-sfu/job.yml
```
# delete manifests
kubectl delete -f ./deployments/k8s/ion-sfu/configmap.yml
kubectl delete -f ./deployments/k8s/ion-sfu/job.yml
```

- janus

``` zsh
# update or create manifests
kubectl apply -f ./deployments/k8s/janus/configmap.yml
kubectl apply -f ./deployments/k8s/janus/job.yml
``` zsh
# update or create manifests
kubectl apply -f ./deployments/k8s/janus/configmap.yml
kubectl apply -f ./deployments/k8s/janus/job.yml

# delete manifests
kubectl delete -f ./deployments/k8s/janus/configmap.yml
kubectl delete -f ./deployments/k8s/janus/job.yml
```
# delete manifests
kubectl delete -f ./deployments/k8s/janus/configmap.yml
kubectl delete -f ./deployments/k8s/janus/job.yml
```

### Troubleshooting image


### troubleshooting image

- docker container run --entrypoint /bin/sh -it --rm ghcr.io/snapp-incubator/ghodrat-janus:latest
```bash
docker container run --entrypoint /bin/sh -it --rm ghcr.io/snapp-incubator/ghodrat-janus:latest
```
3 changes: 2 additions & 1 deletion internal/client/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
// InitiatePeerConnection returns webrtc-peer-connection with opus media-engine.
func (client *Client) CreatePeerConnection(iceConnectedCtxCancel context.CancelFunc) {
client.iceConnectedCtxCancel = iceConnectedCtxCancel

var err error

// A MediaEngine defines the codecs supported by a PeerConnection
Expand All @@ -36,7 +37,7 @@ func (client *Client) CreatePeerConnection(iceConnectedCtxCancel context.CancelF
api := webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine))

// Prepare the configuration
// nolint: exhaustivestruct
// nolint: exhaustruct
config := webrtc.Configuration{
SDPSemantics: webrtc.SDPSemanticsUnifiedPlanWithFallback,
ICEServers: []webrtc.ICEServer{
Expand Down
1 change: 1 addition & 0 deletions internal/client/description.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func (client *Client) GetLocalDescription() *webrtc.SessionDescription {

func (client *Client) SetRemoteDescription(sdp webrtc.SessionDescription) {
client.Logger.Info("remote description", zap.Any("sdp", sdp))

if err := client.connection.SetRemoteDescription(sdp); err != nil {
client.Logger.Fatal("failed to set remote SDP answer", zap.Error(err))
}
Expand Down
1 change: 1 addition & 0 deletions internal/client/ice.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (client *Client) AddIceCandidate(c *webrtc.ICECandidateInit) {

func (client *Client) onICEConnectionStateChange(connectionState webrtc.ICEConnectionState) {
client.Logger.Info("connection state has changed", zap.String("state", connectionState.String()))

if connectionState == webrtc.ICEConnectionStateConnected {
client.iceConnectedCtxCancel()
}
Expand Down
51 changes: 35 additions & 16 deletions internal/client/track.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"context"
"errors"
"io"
"os"
"strings"
Expand All @@ -13,35 +14,37 @@ import (
"github.com/pion/webrtc/v3/pkg/media/oggreader"
)

// nolint: exhaustruct, gochecknoglobals
var (
audioTrackCodecCapability = webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeOpus}
audioTrackCodecId = "audio"
audioTrackCodecID = "audio"

videoTrackCodecCapability = webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeVP8}
videoTrackCodecId = "video"
videoTrackCodecID = "video"
)

func (client *Client) ReadTrack(doneChannel chan bool, connectedCtx context.Context) {
func (client *Client) ReadTrack(doneChannel chan bool, connectedCtx context.Context) { // nolint; revive
_, err := os.Stat(client.Config.TrackAddress)
if os.IsNotExist(err) {
panic("Track Not Exists")
}

var trackCodecCapability webrtc.RTPCodecCapability
var trackCodecId string

mimeType := client.Config.RTPCodec.MimeType
isAudioTrack := strings.Split(mimeType, "/")[0] == "audio"
var (
trackCodecCapability webrtc.RTPCodecCapability
trackCodecID string
mimeType = client.Config.RTPCodec.MimeType
isAudioTrack = strings.Split(mimeType, "/")[0] == "audio"
)

if isAudioTrack {
trackCodecCapability = audioTrackCodecCapability
trackCodecId = audioTrackCodecId
trackCodecID = audioTrackCodecID
} else {
trackCodecCapability = videoTrackCodecCapability
trackCodecId = videoTrackCodecId
trackCodecID = videoTrackCodecID
}

track, trackErr := webrtc.NewTrackLocalStaticSample(trackCodecCapability, trackCodecId, "ghodrat")
track, trackErr := webrtc.NewTrackLocalStaticSample(trackCodecCapability, trackCodecID, "ghodrat")
if trackErr != nil {
panic(trackErr)
}
Expand All @@ -65,6 +68,7 @@ func (client *Client) ReadTrack(doneChannel chan bool, connectedCtx context.Cont
// like NACK this needs to be called.
func readRTCP(rtpSender *webrtc.RTPSender) {
rtcpBuf := make([]byte, 1500)

for {
if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil {
return
Expand All @@ -74,7 +78,9 @@ func readRTCP(rtpSender *webrtc.RTPSender) {

const oggPageDuration = time.Millisecond * 20

func audioTrack(address string, doneChannel chan bool, track *webrtc.TrackLocalStaticSample, connectedCtx context.Context) {
func audioTrack(address string, doneChannel chan bool,
track *webrtc.TrackLocalStaticSample, connectedCtx context.Context,
) {
// Open a OGG file and start reading using our OGGReader
file, oggErr := os.Open(address)
if oggErr != nil {
Expand All @@ -97,10 +103,12 @@ func audioTrack(address string, doneChannel chan bool, track *webrtc.TrackLocalS
// * avoids accumulating skew, just calling time.Sleep didn't compensate for the time spent parsing the data
// * works around latency issues with Sleep (see https://github.com/golang/go/issues/44343)
ticker := time.NewTicker(oggPageDuration)

for ; true; <-ticker.C {
pageData, pageHeader, oggErr := ogg.ParseNextPage()
if oggErr == io.EOF {
if errors.Is(oggErr, io.EOF) {
doneChannel <- true

return
}

Expand All @@ -113,14 +121,18 @@ func audioTrack(address string, doneChannel chan bool, track *webrtc.TrackLocalS
lastGranule = pageHeader.GranulePosition
sampleDuration := time.Duration((sampleCount/48000)*1000) * time.Millisecond

// nolint: exhaustruct
sample := media.Sample{Data: pageData, Duration: sampleDuration}
if oggErr = track.WriteSample(sample); oggErr != nil {
panic(oggErr)
}
}
}

func videoTrack(address string, doneChannel chan bool, track *webrtc.TrackLocalStaticSample, connectedCtx context.Context) {
// nolint: revive
func videoTrack(address string, doneChannel chan bool,
track *webrtc.TrackLocalStaticSample, connectedCtx context.Context,
) {
// Open a IVF file and start reading using our IVFReader
file, ivfErr := os.Open(address)
if ivfErr != nil {
Expand All @@ -141,18 +153,25 @@ func videoTrack(address string, doneChannel chan bool, track *webrtc.TrackLocalS
// It is important to use a time.Ticker instead of time.Sleep because
// * avoids accumulating skew, just calling time.Sleep didn't compensate for the time spent parsing the data
// * works around latency issues with Sleep (see https://github.com/golang/go/issues/44343)
ticker := time.NewTicker(time.Millisecond * time.Duration((float32(header.TimebaseNumerator)/float32(header.TimebaseDenominator))*1000))
ticker := time.NewTicker(
time.Millisecond * time.Duration(
(float32(header.TimebaseNumerator)/float32(header.TimebaseDenominator))*1000,
),
)

for ; true; <-ticker.C {
frame, _, ivfErr := ivf.ParseNextFrame()
if ivfErr == io.EOF {
if errors.Is(ivfErr, io.EOF) {
doneChannel <- true

return
}

if ivfErr != nil {
panic(ivfErr)
}

// nolint: exhaustruct
sample := media.Sample{Data: frame, Duration: time.Second}
if ivfErr = track.WriteSample(sample); ivfErr != nil {
panic(ivfErr)
Expand Down
7 changes: 4 additions & 3 deletions internal/cmd/ion/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@ const (
)

func Command() *cobra.Command {
// nolint: exhaustruct
cmd := &cobra.Command{Use: use, Short: short, Long: long, Example: example, Run: run}

return cmd
}

func run(cmd *cobra.Command, _ []string) {
func run(_ *cobra.Command, _ []string) {
configs := config.New()

lg := logger.NewZap(configs.Logger)

//var waitGroup sync.WaitGroup
// var waitGroup sync.WaitGroup

//waitGroup.Add(configs.CallCount)
// waitGroup.Add(configs.CallCount)

engine := ion.NewEngine(nil, lg)

Expand Down
12 changes: 7 additions & 5 deletions internal/cmd/ion_sfu/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ const (
)

func Command() *cobra.Command {
// nolint: exhaustivestruct
// nolint: exhaustruct
cmd := &cobra.Command{Use: use, Short: short, Run: run, PreRun: preRun}

return cmd
}

func preRun(cmd *cobra.Command, _ []string) {
func preRun(_ *cobra.Command, _ []string) {
// nolint: staticcheck
rand.Seed(time.Now().UnixNano())
}

Expand All @@ -35,21 +36,22 @@ func run(_ *cobra.Command, _ []string) {
lg := logger.NewZap(configs.Logger)

var waitGroup sync.WaitGroup

waitGroup.Add(configs.CallCount)

for index := 0; index < configs.CallCount; index++ {
zap := lg.Named(fmt.Sprintf("goroutine: %d", index+1))

server := ion_sfu.Ion_sfu{
Config: configs.Ion_sfu,
server := ion_sfu.IonSfu{
Config: configs.IonSfu,
Logger: zap,
Client: &client.Client{
Config: configs.Client,
Logger: zap,
},
}

go func(server ion_sfu.Ion_sfu) {
go func(server ion_sfu.IonSfu) {
doneChannel := make(chan bool)
server.StartCall(doneChannel)
<-doneChannel
Expand Down
6 changes: 4 additions & 2 deletions internal/cmd/janus/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ const (
)

func Command() *cobra.Command {
// nolint: exhaustivestruct
// nolint: exhaustruct
cmd := &cobra.Command{Use: use, Short: short, Run: run, PreRun: preRun}

return cmd
}

func preRun(cmd *cobra.Command, _ []string) {
func preRun(_ *cobra.Command, _ []string) {
// nolint: staticcheck
rand.Seed(time.Now().UnixNano())
}

Expand All @@ -35,6 +36,7 @@ func run(_ *cobra.Command, _ []string) {
lg := logger.NewZap(configs.Logger)

var waitGroup sync.WaitGroup

waitGroup.Add(configs.CallCount)

for index := 0; index < configs.CallCount; index++ {
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const (
const ExitFailure = 1

func Execute() {
// nolint: exhaustivestruct
// nolint: exhaustruct
cmd := &cobra.Command{Short: short, Long: long}

cmd.AddCommand(janus.Command(), ion_sfu.Command())
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Config struct {
CallCount int `koanf:"call-count"`
Client *client.Config `koanf:"client"`
Janus *janus.Config `koanf:"janus"`
Ion_sfu *ion_sfu.Config `koanf:"ion-sfu"`
IonSfu *ion_sfu.Config `koanf:"ion-sfu"`
}

// New reads configuration with viper.
Expand Down
Loading

0 comments on commit 1370b26

Please sign in to comment.