func (s *server) Subscribe(ctx context.Context, protocol string, ids *ttnpb.ApplicationIdentifiers, global bool) (*io.Subscription, error) {
	s.subscriptionsMu.RLock()
	err := s.subscribeError
	s.subscriptionsMu.RUnlock()
	if err != nil {
		return nil, err
	}
	sub := io.NewSubscription(ctx, protocol, ids)
	s.subscriptionsMu.Lock()
	if ids != nil {
		s.appSubs[unique.ID(ctx, ids)] = append(s.appSubs[unique.ID(ctx, ids)], sub)
	} else {
		s.bcastSubs = append(s.bcastSubs, sub)
	}
	s.subscriptionsMu.Unlock()
	select {
	case s.subscriptionsCh <- sub:
	default:
	}
	return sub, nil
}
Subscribe implements io.Server.
package mock
import (
	"context"
	"sync"
	"go.thethings.network/lorawan-stack/v3/pkg/applicationserver/io"
	"go.thethings.network/lorawan-stack/v3/pkg/component"
	"go.thethings.network/lorawan-stack/v3/pkg/ratelimit"
	"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
	"go.thethings.network/lorawan-stack/v3/pkg/unique"
)
type server struct {
	*component.Component
	subscriptionsMu sync.RWMutex
	appSubs         map[string][]*io.Subscription
	bcastSubs       []*io.Subscription
	subscriptionsCh chan *io.Subscription
	downlinkQueueMu sync.RWMutex
	downlinkQueue   map[string][]*ttnpb.ApplicationDownlink
	subscribeError  error
	applicationUps  map[string][]*ttnpb.ApplicationUplink
}
type Server interface {
	io.Server
	SetSubscribeError(error)
	Subscriptions() <-chan *io.Subscription
	SetUplinks(ctx context.Context, ids ttnpb.EndDeviceIdentifiers, ups ...*ttnpb.ApplicationUplink)
}
func NewServer(c *component.Component) Server {
	return &server{
		Component:       c,
		appSubs:         make(map[string][]*io.Subscription),
		subscriptionsCh: make(chan *io.Subscription, 10),
		downlinkQueue:   make(map[string][]*ttnpb.ApplicationDownlink),
	}
}
func (s *server) FillContext(ctx context.Context) context.Context {
	return s.Component.FillContext(ctx)
}
func (s *server) Publish(ctx context.Context, up *ttnpb.ApplicationUp) error {
	s.subscriptionsMu.RLock()
	defer s.subscriptionsMu.RUnlock()
	for _, sub := range s.appSubs[unique.ID(ctx, up.ApplicationIdentifiers)] {
		if err := sub.Publish(ctx, up); err != nil {
			return err
		}
	}
	for _, sub := range s.bcastSubs {
		if err := sub.Publish(ctx, up); err != nil {
			return err
		}
	}
	return nil
}