Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions app/broadcasting/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package broadcasting

import (
"time"

"github.com/goravel/framework/broadcasting"
contracts "github.com/goravel/framework/contracts/broadcasting"
)

type OrderShipped struct {
OrderID uint
OrderData map[string]any
ShouldFire bool
QueueName string
Conns []string
QueueConn string
DelayedAt time.Time
Retries int
Backoff time.Duration
Timeout time.Duration
}

func (e *OrderShipped) BroadcastOn() []contracts.Channel {
return []contracts.Channel{
broadcasting.PrivateChannel("orders." + itoa(e.OrderID)),
}
}

func (e *OrderShipped) BroadcastAs() string {
return "order.shipped"
}

func (e *OrderShipped) BroadcastWith() map[string]any {
return map[string]any{"order": e.OrderData}
}

func (e *OrderShipped) BroadcastWhen() bool {
return e.ShouldFire
}

func (e *OrderShipped) BroadcastQueue() string {
return e.QueueName
}

func (e *OrderShipped) BroadcastConnections() []string {
return e.Conns
}

func (e *OrderShipped) BroadcastQueueConnection() string {
return e.QueueConn
}

func (e *OrderShipped) BroadcastDelay() time.Time {
return e.DelayedAt
}

func (e *OrderShipped) BroadcastTries() int {
return e.Retries
}

func (e *OrderShipped) BroadcastBackoff() time.Duration {
return e.Backoff
}

func (e *OrderShipped) BroadcastTimeout() time.Duration {
return e.Timeout
}

type OrderShippedNow struct {
OrderID uint
OrderData map[string]any
}

func (e *OrderShippedNow) BroadcastOn() []contracts.Channel {
return []contracts.Channel{
broadcasting.PublicChannel("orders"),
}
}

func (e *OrderShippedNow) BroadcastAs() string {
return "order.shipped"
}

func (e *OrderShippedNow) BroadcastWith() map[string]any {
return map[string]any{"order": e.OrderData}
}

func (e *OrderShippedNow) BroadcastWhen() bool {
return true
}

func (e *OrderShippedNow) BroadcastNow() bool {
return true
}

type EmptyEvent struct{}

func (e *EmptyEvent) BroadcastOn() []contracts.Channel {
return nil
}

func (e *EmptyEvent) BroadcastAs() string {
return "empty.event"
}

func (e *EmptyEvent) BroadcastWith() map[string]any {
return nil
}

func (e *EmptyEvent) BroadcastWhen() bool {
return false
}

func itoa(n uint) string {
if n == 0 {
return "0"
}
var digits []byte
for n > 0 {
digits = append([]byte{byte('0' + n%10)}, digits...)
n /= 10
}
return string(digits)
}
9 changes: 9 additions & 0 deletions app/facades/broadcast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package facades

import (
"github.com/goravel/framework/contracts/broadcasting"
)

func Broadcast() broadcasting.Broadcast {
return App().MakeBroadcast()
}
15 changes: 15 additions & 0 deletions app/services/mock_examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/goravel/framework/contracts/queue"
"github.com/goravel/framework/filesystem"

appbroadcasting "goravel/app/broadcasting"
"goravel/app/events"
"goravel/app/facades"
"goravel/app/jobs"
Expand Down Expand Up @@ -136,3 +137,17 @@ func Validation() string {
func View() bool {
return facades.View().Exists("welcome.tmpl")
}

func BroadcastChannel() {
facades.Broadcast().Channel("orders.{orderId}", func(user any, channelName string, params map[string]string) bool {
return params["orderId"] == "1"
})
}

func BroadcastDispatch() error {
return facades.Broadcast().Dispatch(&appbroadcasting.OrderShipped{
OrderID: 1,
OrderData: map[string]any{"id": 1},
ShouldFire: true,
})
}
19 changes: 19 additions & 0 deletions app/services/mock_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/goravel/framework/contracts/mail"
"github.com/goravel/framework/filesystem"
mocksbroadcasting "github.com/goravel/framework/mocks/broadcasting"
"github.com/goravel/framework/testing/mock"
testifymock "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -216,3 +217,21 @@ func (s *MockExamplesTestSuite) TestView() {

s.True(View())
}

func (s *MockExamplesTestSuite) TestBroadcastChannel() {
mockFactory := mock.Factory()
mockBroadcast := mocksbroadcasting.NewBroadcast(s.T())
mockFactory.App().EXPECT().MakeBroadcast().Return(mockBroadcast).Once()
mockBroadcast.EXPECT().Channel("orders.{orderId}", testifymock.Anything).Once()

BroadcastChannel()
}

func (s *MockExamplesTestSuite) TestBroadcastDispatch() {
mockFactory := mock.Factory()
mockBroadcast := mocksbroadcasting.NewBroadcast(s.T())
mockFactory.App().EXPECT().MakeBroadcast().Return(mockBroadcast).Once()
mockBroadcast.EXPECT().Dispatch(testifymock.Anything).Return(nil).Once()

s.Nil(BroadcastDispatch())
}
1 change: 1 addition & 0 deletions bootstrap/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func Boot() contractsfoundation.Application {
facades.Schema().Extend(schema.Extension{
Models: []any{models.User{}},
})
routes.Channels()
}).
WithConfig(config.Boot).
Create()
Expand Down
4 changes: 3 additions & 1 deletion bootstrap/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/goravel/fiber"
"github.com/goravel/framework/ai"
"github.com/goravel/framework/auth"
"github.com/goravel/framework/broadcasting"
"github.com/goravel/framework/cache"
"github.com/goravel/framework/contracts/foundation"
"github.com/goravel/framework/crypt"
Expand All @@ -27,7 +28,6 @@ import (
"github.com/goravel/framework/translation"
"github.com/goravel/framework/validation"
"github.com/goravel/framework/view"
"goravel/packages/viewtest"
"github.com/goravel/gemini"
"github.com/goravel/gin"
"github.com/goravel/minio"
Expand All @@ -39,6 +39,7 @@ import (
"github.com/goravel/s3"
"github.com/goravel/sqlite"
"github.com/goravel/sqlserver"
"goravel/packages/viewtest"
)

func Providers() []foundation.ServiceProvider {
Expand All @@ -54,6 +55,7 @@ func Providers() []foundation.ServiceProvider {
&auth.ServiceProvider{},
&crypt.ServiceProvider{},
&queue.ServiceProvider{},
&broadcasting.ServiceProvider{},
&event.ServiceProvider{},
&grpc.ServiceProvider{},
&hash.ServiceProvider{},
Expand Down
37 changes: 37 additions & 0 deletions config/broadcasting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package config

import "goravel/app/facades"

func init() {
config := facades.Config()
config.Add("broadcasting", map[string]any{
"default": config.Env("BROADCAST_CONNECTION", "log"),

"connections": map[string]any{
"pusher": map[string]any{
"driver": "pusher",
"key": config.Env("PUSHER_APP_KEY", "test-key"),
"secret": config.Env("PUSHER_APP_SECRET", "test-secret"),
"app_id": config.Env("PUSHER_APP_ID", "test-app"),
"options": map[string]any{
"cluster": config.Env("PUSHER_APP_CLUSTER", "mt1"),
"host": config.Env("PUSHER_HOST", "127.0.0.1"),
"port": config.Env("PUSHER_PORT", 6001),
"scheme": config.Env("PUSHER_SCHEME", "http"),
},
},
"log": map[string]any{
"driver": "log",
},
"null": map[string]any{
"driver": "null",
},
},

"auth": map[string]any{
"enabled": config.Env("BROADCAST_AUTH_ENABLED", true),
"path": config.Env("BROADCAST_AUTH_PATH", "/broadcasting/auth"),
"middleware": []string{},
},
})
}
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
version: '3.8'

services:
relay:
image: darknautica/relay:latest
restart: always
volumes:
- ./docker/relay/apps.json:/relay/apps.json
ports:
- "6001:6001"

otel-collector:
image: otel/opentelemetry-collector-contrib:latest
restart: always
Expand Down
10 changes: 10 additions & 0 deletions docker/relay/apps.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"id": "test-app",
"key": "test-key",
"secret": "test-secret",
"max_connections": 1000,
"history": true,
"history_limit": 100
}
]
24 changes: 12 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/goravel/cos v1.18.0
github.com/goravel/example-proto v0.0.1
github.com/goravel/fiber v1.18.0
github.com/goravel/framework v1.18.0
github.com/goravel/framework v1.18.1-0.20260724081045-8b12654652e5
github.com/goravel/gemini v1.18.0
github.com/goravel/gin v1.18.0
github.com/goravel/minio v1.18.0
Expand All @@ -32,7 +32,7 @@ require (
go.opentelemetry.io/otel v1.44.0
go.opentelemetry.io/otel/metric v1.44.0
go.opentelemetry.io/otel/trace v1.44.0
google.golang.org/grpc v1.81.1
google.golang.org/grpc v1.82.0
google.golang.org/protobuf v1.36.11
)

Expand Down Expand Up @@ -235,16 +235,16 @@ require (
go.uber.org/atomic v1.11.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/arch v0.22.0 // indirect
golang.org/x/crypto v0.53.0 // indirect
golang.org/x/exp v0.0.0-20260611194520-c48552f49976 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/sync v0.21.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/term v0.44.0 // indirect
golang.org/x/text v0.38.0 // indirect
golang.org/x/crypto v0.54.0 // indirect
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 // indirect
golang.org/x/mod v0.38.0 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.40.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.47.0 // indirect
golang.org/x/tools v0.48.0 // indirect
google.golang.org/genai v1.58.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
Expand All @@ -257,4 +257,4 @@ require (
gorm.io/plugin/dbresolver v1.6.2 // indirect
)

replace github.com/goravel/framework => github.com/goravel/framework v1.18.0
replace github.com/goravel/framework => github.com/goravel/framework v1.18.1-0.20260724081045-8b12654652e5
Loading
Loading