256 lines
6.3 KiB
Go
256 lines
6.3 KiB
Go
package localserver
|
|
|
|
import (
|
|
"context"
|
|
"crypto/x509"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
)
|
|
|
|
var logger *log.Logger = new(log.Logger)
|
|
var dbLogger *BadgerLogger = &BadgerLogger{
|
|
Logger: logger,
|
|
}
|
|
|
|
type BadgerLogger struct {
|
|
*log.Logger
|
|
}
|
|
|
|
func (b *BadgerLogger) Debugf(message string, data ...interface{}) {
|
|
b.Println(data...)
|
|
}
|
|
|
|
func (b *BadgerLogger) Errorf(message string, data ...interface{}) {
|
|
b.Println(data...)
|
|
}
|
|
|
|
func (b *BadgerLogger) Infof(message string, data ...interface{}) {
|
|
b.Println(data...)
|
|
}
|
|
|
|
func (b *BadgerLogger) Warningf(message string, data ...interface{}) {
|
|
b.Println(data...)
|
|
}
|
|
|
|
type (
|
|
// LocalServerHandlerMiddleware interface {
|
|
// Process(ctx context.Context, req *http.Request, w http.ResponseWriter) (err error)
|
|
// }
|
|
|
|
SignalingClientManagerMiddleware interface {
|
|
Process(ctx context.Context, req *SignalingMessage, stream SignalingService_LinkClient) (err error)
|
|
}
|
|
|
|
// LocalServerHandler struct {
|
|
// middlewares []LocalServerHandlerMiddleware
|
|
// }
|
|
|
|
LocalServer struct {
|
|
ID string
|
|
GrpcClientManager *SignalingClientManager
|
|
}
|
|
|
|
SignalingClientManager struct {
|
|
GrpcConn grpc.ClientConnInterface
|
|
SignalingManagerClient SignalingServiceClient
|
|
GrpcLinkClient SignalingService_LinkClient
|
|
middlewares []SignalingClientManagerMiddleware
|
|
}
|
|
|
|
CustomMenuItem struct {
|
|
//MenuItem *systray.MenuItem
|
|
ID string
|
|
State bool
|
|
SubMenus []*CustomMenuItem
|
|
CallBack func(bool)
|
|
}
|
|
|
|
ReqType string
|
|
|
|
LocalServerRequest struct {
|
|
ReqType ReqType
|
|
Payload map[string]interface{}
|
|
}
|
|
)
|
|
|
|
var dataPath = ""
|
|
|
|
func NewLocalServer(grpcAddr uint, appDataPath, id, token string) (localServer *LocalServer, err error) {
|
|
dataPath = appDataPath
|
|
zoneManager, err := NewZoneManager(id, token)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
chatManager, err := NewChatManager(id, token)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
squadManager, err := NewSquadManager(id, token)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
zoneGrpcMiddleware := NewZoneGrpcMiddleware(zoneManager)
|
|
chatGrpcMiddleware := NewChatGrpcMiddleware(chatManager)
|
|
squadGrpcMiddleware := NewSquadGrpcMiddleware(squadManager)
|
|
signalingClientManager, err := NewGrpcClientManager(grpcAddr, id, zoneGrpcMiddleware, chatGrpcMiddleware, squadGrpcMiddleware)
|
|
if err != nil {
|
|
return
|
|
}
|
|
zoneManager.stream = signalingClientManager.GrpcLinkClient
|
|
zoneGrpcMiddleware.stream = signalingClientManager.GrpcLinkClient
|
|
chatManager.stream = signalingClientManager.GrpcLinkClient
|
|
chatGrpcMiddleware.stream = signalingClientManager.GrpcLinkClient
|
|
squadManager.stream = signalingClientManager.GrpcLinkClient
|
|
squadGrpcMiddleware.stream = signalingClientManager.GrpcLinkClient
|
|
localServer = &LocalServer{
|
|
ID: id,
|
|
GrpcClientManager: signalingClientManager,
|
|
}
|
|
return
|
|
}
|
|
|
|
func NewGrpcClientManager(addr uint, id string, middleware ...SignalingClientManagerMiddleware) (signalingClientManager *SignalingClientManager, err error) {
|
|
conn, signalingClient, signalingLinkClient, err := NewGrpcConn(fmt.Sprintf("dev.zippytal.com:%d", addr), id)
|
|
if err != nil {
|
|
return
|
|
}
|
|
signalingClientManager = &SignalingClientManager{
|
|
GrpcConn: conn,
|
|
SignalingManagerClient: signalingClient,
|
|
GrpcLinkClient: signalingLinkClient,
|
|
middlewares: middleware,
|
|
}
|
|
return
|
|
}
|
|
|
|
func NewGrpcConn(addr string, id string) (conn grpc.ClientConnInterface, signalingClient SignalingServiceClient, signalingLinkClient SignalingService_LinkClient, err error) {
|
|
res, err := http.Get("https://zippytal.com/certificate")
|
|
if err != nil {
|
|
return
|
|
}
|
|
bytes, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return
|
|
}
|
|
cp := x509.NewCertPool()
|
|
if !cp.AppendCertsFromPEM(bytes) {
|
|
err = fmt.Errorf("certificate format not supported")
|
|
return
|
|
}
|
|
creds := credentials.NewClientTLSFromCert(cp, "dev.zippytal.com")
|
|
var opts []grpc.DialOption = []grpc.DialOption{grpc.WithTransportCredentials(creds)}
|
|
conn, err = grpc.Dial(addr, opts...)
|
|
if err != nil {
|
|
fmt.Println("over there")
|
|
return
|
|
}
|
|
signalingClient = NewSignalingServiceClient(conn)
|
|
signalingLinkClient, err = signalingClient.Link(context.Background())
|
|
if err != nil {
|
|
fmt.Println("really there")
|
|
// logger.Println(err)
|
|
return
|
|
}
|
|
payload := map[string]any{
|
|
"init": "init",
|
|
}
|
|
bs, err := json.Marshal(payload)
|
|
if err != nil {
|
|
// logger.Println(err)
|
|
return
|
|
}
|
|
if err = signalingLinkClient.Send(&SignalingMessage{
|
|
Type: "init",
|
|
From: id,
|
|
To: "server",
|
|
Payload: bs,
|
|
}); err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// func NewLocalServerHandler(middlewares ...LocalServerHandlerMiddleware) (localServerHandler *LocalServerHandler) {
|
|
// localServerHandler = &LocalServerHandler{
|
|
// middlewares: middlewares,
|
|
// }
|
|
// return
|
|
// }
|
|
|
|
// func (lsh *LocalServerHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|
// wg, done, errCh := &sync.WaitGroup{}, make(chan struct{}), make(chan error)
|
|
// for _, middleware := range lsh.middlewares {
|
|
// wg.Add(1)
|
|
// go func(m LocalServerHandlerMiddleware) {
|
|
// err := m.Process(req.Context(), req, w)
|
|
// if err != nil {
|
|
// errCh <- err
|
|
// }
|
|
// wg.Done()
|
|
// }(middleware)
|
|
// }
|
|
// go func() {
|
|
// wg.Wait()
|
|
// done <- struct{}{}
|
|
// }()
|
|
// select {
|
|
// case <-req.Context().Done():
|
|
// case <-done:
|
|
// case err := <-errCh:
|
|
// // logger.Println(err)
|
|
// }
|
|
// }
|
|
|
|
func (gcm *SignalingClientManager) Handle(ctx context.Context) (err error) {
|
|
done, errCh := make(chan struct{}), make(chan error)
|
|
go func() {
|
|
wg := new(sync.WaitGroup)
|
|
for {
|
|
res, err := gcm.GrpcLinkClient.Recv()
|
|
if err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
for _, middleware := range gcm.middlewares {
|
|
wg.Add(1)
|
|
go func(m SignalingClientManagerMiddleware) {
|
|
defer wg.Done()
|
|
if err := m.Process(ctx, res, gcm.GrpcLinkClient); err != nil {
|
|
// logger.Println(err)
|
|
}
|
|
}(middleware)
|
|
}
|
|
wg.Wait()
|
|
}
|
|
}()
|
|
select {
|
|
case <-gcm.GrpcLinkClient.Context().Done():
|
|
// logger.Println("grpc context")
|
|
err = gcm.GrpcLinkClient.Context().Err()
|
|
return
|
|
case <-ctx.Done():
|
|
// logger.Println("app context")
|
|
err = ctx.Err()
|
|
return
|
|
case <-done:
|
|
// logger.Println("done")
|
|
return
|
|
case err = <-errCh:
|
|
// logger.Println("done with error")
|
|
if closeErr := gcm.GrpcLinkClient.CloseSend(); closeErr != nil {
|
|
return closeErr
|
|
}
|
|
return
|
|
}
|
|
}
|