Zippytal-Node/chatGrpcMiddleware.go

177 lines
4.9 KiB
Go

package localserver
import (
"context"
"encoding/json"
"strconv"
"github.com/pion/webrtc/v3"
)
const (
NEW_CHAT = "new_chat"
CHAT_DELETED = "chat_deleted"
CHAT_SYNCED = "chat_synced"
SYNC_CHAT = "sync_chat"
EXPORT_CHAT = "export_chat"
CHAT_EXPORTED = "chat_exported"
GET_NODE_CHATS = "get_node_chats"
LEAVE_CHAT = "leave_chat"
CHAT_WEBRTC_OFFER = "chat_webrtc_offer"
CHAT_WEBRTC_ANSWER = "chat_webrtc_answer"
CHAT_WEBRTC_COUNTER_OFFER = "chat_webrtc_counter_offer"
CHAT_WEBRTC_RENNEGOTIATION_OFFER = "chat_webrtc_rennegotiation_offer"
CHAT_WEBRTC_RENNEGOTIATION_ANSWER = "chat_werbtc_rennegotiation_answer"
CHAT_WEBRTC_CANDIDATE = "chat_webrtc_candidate"
)
type ChatGrpcMiddleware struct {
Manager *ChatsManager
stream SignalingService_LinkClient
}
func NewChatGrpcMiddleware(manager *ChatsManager) (chatGrpcMiddleware *ChatGrpcMiddleware) {
chatGrpcMiddleware = &ChatGrpcMiddleware{
Manager: manager,
}
return
}
func (cm *ChatGrpcMiddleware) signalCandidate(to string, candidate *webrtc.ICECandidate) (err error) {
bs, err := json.Marshal((map[string]string{
"from": NodeID,
"to": to,
"candidate": candidate.ToJSON().Candidate,
"sdpMid": *candidate.ToJSON().SDPMid,
"sdpMLineIndex": strconv.Itoa(int(*candidate.ToJSON().SDPMLineIndex)),
}))
if err != nil {
return
}
err = cm.stream.Send(&SignalingMessage{
Type: CHAT_WEBRTC_CANDIDATE,
From: NodeID,
To: to,
Payload: bs,
})
return
}
func (cm *ChatGrpcMiddleware) Process(ctx context.Context, req *SignalingMessage, streram SignalingService_LinkClient) (err error) {
done, errCh := make(chan struct{}), make(chan error)
go func() {
var payload map[string]string
if e := json.Unmarshal(req.Payload, &payload); e != nil {
errCh <- e
return
}
switch req.GetType() {
case NEW_CHAT:
if err := validateRequest(payload, "chatID", "initiator", "target", "initiatorHostId", "targetHostId"); err != nil {
errCh <- err
return
}
chat, err := NewNodeChat(payload["chatID"], payload["chatID"], payload["initiator"], payload["target"], payload["initiatorHostId"], payload["targetHostId"], false)
if err != nil {
errCh <- err
return
}
_ = atomicallyExecute(cm.Manager.chatsFlag, func() (err error) {
cm.Manager.Chats[chat.ID] = chat
return
})
case CHAT_DELETED:
if err := validateRequest(payload, "chatID"); err != nil {
return
}
if err := cm.Manager.DeleteChat(payload["chatID"]); err != nil {
errCh <- err
return
}
case CHAT_EXPORTED:
//todo: implement chat exported
case EXPORT_CHAT:
//todo: implement export chat exported
case CHAT_SYNCED:
//todo: implement chat synced
case SYNC_CHAT:
//todo: implement sync chat
case CHAT_WEBRTC_OFFER:
if err := validateRequest(payload, SDP); err != nil {
errCh <- err
return
}
if err := cm.Manager.HandleOffer(ctx, req.GetFrom(), req.GetTo(), payload, cm.signalCandidate); err != nil {
errCh <- err
return
}
case CHAT_WEBRTC_ANSWER:
if err := validateRequest(payload, SDP); err != nil {
errCh <- err
return
}
if err := cm.Manager.HandleAnswer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil {
errCh <- err
return
}
case CHAT_WEBRTC_COUNTER_OFFER:
if err := cm.Manager.HandleCounterOffer(ctx, req.GetFrom(), req.GetTo(), payload); err != nil {
errCh <- err
return
}
case CHAT_WEBRTC_RENNEGOTIATION_OFFER:
if err := validateRequest(payload, SDP); err != nil {
errCh <- err
return
}
if err := cm.Manager.HandleRennegotiationOffer(req.GetFrom(), payload[SDP]); err != nil {
errCh <- err
return
}
case CHAT_WEBRTC_RENNEGOTIATION_ANSWER:
if err := validateRequest(payload, SDP); err != nil {
errCh <- err
return
}
if err := cm.Manager.HandleRennegotiationAnswer(req.GetFrom(), payload[SDP]); err != nil {
errCh <- err
return
}
case CHAT_WEBRTC_CANDIDATE:
if err := validateRequest(payload, "candidate", "sdpMLineIndex", "sdpMid"); err != nil {
errCh <- err
return
}
logger.Println(payload)
i, err := strconv.Atoi(payload["sdpMLineIndex"])
if err != nil {
errCh <- err
return
}
SDPMLineIndex := uint16(i)
sdpMid := payload["sdpMid"]
logger.Println(sdpMid, SDPMLineIndex)
if err := cm.Manager.AddCandidate(&webrtc.ICECandidateInit{
Candidate: payload["candidate"],
SDPMid: &sdpMid,
SDPMLineIndex: &SDPMLineIndex,
}, req.GetFrom()); err != nil {
errCh <- err
return
}
default:
logger.Println("no request for chats grpc middleware")
logger.Println(payload)
logger.Println(req.Type)
}
}()
select {
case <-ctx.Done():
return ctx.Err()
case err = <-errCh:
return
case <-done:
return
}
}