func (ar *Aries) GetMessagingController() (api.MessagingController, error) {
	endpoints, ok := ar.endpoints[messaging.MsgServiceOperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", messaging.MsgServiceOperationID)
	}
	return &Messaging{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
GetMessagingController returns a Messaging instance.
package rest
import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strings"
	"sync"
	"github.com/google/uuid"
	"nhooyr.io/websocket"
	"nhooyr.io/websocket/wsjson"
	"github.com/hyperledger/aries-framework-go/cmd/aries-agent-mobile/pkg/api"
	"github.com/hyperledger/aries-framework-go/cmd/aries-agent-mobile/pkg/wrappers/config"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/didexchange"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/introduce"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/issuecredential"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/kms"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/ld"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/mediator"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/messaging"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/outofband"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/presentproof"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/vcwallet"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/vdr"
	"github.com/hyperledger/aries-framework-go/pkg/controller/rest/verifiable"
)
type Aries struct {
	endpoints map[string]map[string]*endpoint
	URL          string
	WebsocketURL string
	Token        string
	mutex        sync.RWMutex
	subscribers  map[string]map[string][]api.Handler
}
func NewAries(opts *config.Options) (*Aries, error) {
	if opts == nil || opts.AgentURL == "" {
		return nil, errors.New("no agent url provided")
	}
	endpoints := getControllerEndpoints()
	a := &Aries{
		endpoints:    endpoints,
		URL:          opts.AgentURL,
		Token:        opts.APIToken,
		WebsocketURL: opts.WebsocketURL,
		subscribers:  make(map[string]map[string][]api.Handler),
	}
	go a.startNotificationListener()
	return a, nil
}
type Incoming struct {
	ID      string      `json:"id"`
	Topic   string      `json:"topic"`
	Message interface{} `json:"message"`
}
func (ar *Aries) startNotificationListener() {
	if ar.WebsocketURL == "" {
		return
	}
	conn, _, err := websocket.Dial(context.Background(), ar.WebsocketURL, nil)  
	if err != nil {
		logger.Errorf("notification listener: websocket dial: %v", err)
		return
	}
	defer func() {
		err = conn.Close(websocket.StatusNormalClosure, "closing the connection")
		if err != nil && websocket.CloseStatus(err) != websocket.StatusNormalClosure {
			logger.Errorf("notification listener: close connection: %v", err)
		}
	}()
	for {
		var incoming *Incoming
		if err := wsjson.Read(context.Background(), conn, &incoming); err != nil {
			if websocket.CloseStatus(err) != websocket.StatusNormalClosure {
				logger.Errorf("notification listener: read: close connection: %v", err)
			}
			if websocket.CloseStatus(err) != -1 {
				return
			}
			continue
		}
		ar.notifySubscribers(incoming)
	}
}
func (ar *Aries) notifySubscribers(incoming *Incoming) {
	ar.mutex.RLock()
	defer ar.mutex.RUnlock()
	for _, handlers := range ar.subscribers[incoming.Topic] {
		raw, err := json.Marshal(incoming)
		if err != nil {
			logger.Errorf("notification listener: marshal: %v", err)
			break
		}
		for _, handler := range handlers {
			if err := handler.Handle(incoming.Topic, raw); err != nil {
				logger.Errorf("notification listener: handle: %v", err)
			}
		}
	}
}
func (ar *Aries) RegisterHandler(h api.Handler, topics string) string {
	ar.mutex.Lock()
	defer ar.mutex.Unlock()
	id := uuid.New().String()
	for _, topic := range strings.Split(topics, ",") {
		if ar.subscribers[topic] == nil {
			ar.subscribers[topic] = map[string][]api.Handler{}
		}
		ar.subscribers[topic][id] = append(ar.subscribers[topic][id], h)
	}
	return id
}
func (ar *Aries) UnregisterHandler(id string) {
	ar.mutex.Lock()
	defer ar.mutex.Unlock()
	for topic := range ar.subscribers {
		for key := range ar.subscribers[topic] {
			if key == id {
				delete(ar.subscribers[topic], id)
			}
		}
	}
}
func (ar *Aries) GetIntroduceController() (api.IntroduceController, error) {
	endpoints, ok := ar.endpoints[introduce.OperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", introduce.OperationID)
	}
	return &Introduce{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
func (ar *Aries) GetVerifiableController() (api.VerifiableController, error) {
	endpoints, ok := ar.endpoints[verifiable.VerifiableOperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", verifiable.VerifiableOperationID)
	}
	return &Verifiable{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
func (ar *Aries) GetDIDExchangeController() (api.DIDExchangeController, error) {
	endpoints, ok := ar.endpoints[didexchange.OperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", didexchange.OperationID)
	}
	return &DIDExchange{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
func (ar *Aries) GetIssueCredentialController() (api.IssueCredentialController, error) {
	endpoints, ok := ar.endpoints[issuecredential.OperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", issuecredential.OperationID)
	}
	return &IssueCredential{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
func (ar *Aries) GetPresentProofController() (api.PresentProofController, error) {
	endpoints, ok := ar.endpoints[presentproof.OperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", presentproof.OperationID)
	}
	return &PresentProof{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
func (ar *Aries) GetVDRController() (api.VDRController, error) {
	endpoints, ok := ar.endpoints[vdr.VDROperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", vdr.VDROperationID)
	}
	return &VDR{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}
func (ar *Aries) GetMediatorController() (api.MediatorController, error) {
	endpoints, ok := ar.endpoints[mediator.RouteOperationID]
	if !ok {
		return nil, fmt.Errorf("no endpoints found for controller [%s]", mediator.RouteOperationID)
	}
	return &Mediator{endpoints: endpoints, URL: ar.URL, Token: ar.Token, httpClient: &http.Client{}}, nil
}