177 lines
4.9 KiB
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
|
|
}
|
|
}
|