harmony/pkg/web/client.go

119 lines
1.9 KiB
Go

package web
import (
"encoding/json"
"log"
"strconv"
"time"
"github.com/gorilla/websocket"
"github.com/pion/webrtc/v2"
"github.com/pkg/errors"
)
type Client struct {
ID int
Name string
Status int
Conn *websocket.Conn
PeerConn *webrtc.PeerConnection
In chan *Message
Out chan *Message
AudioTrack *webrtc.Track
Terminated chan bool
}
func NewClient(conn *websocket.Conn) *Client {
c := Client{Conn: conn, Name: "Anonymous", In: make(chan *Message, 10), Out: make(chan *Message, 10), Terminated: make(chan bool)}
go c.handleRead()
go c.handleWrite()
return &c
}
func (c *Client) handleRead() {
var (
messageTypeInt int
messageType MessageType
message []byte
err error
)
for {
c.Conn.SetReadDeadline(time.Now().Add(1 * time.Minute))
messageTypeInt, message, err = c.Conn.ReadMessage()
if err != nil || c.Status == -1 {
c.Close()
return
}
messageType = MessageType(messageTypeInt)
in := Message{}
if messageType == 2 {
in.T = messageType
in.M = message
} else {
err = json.Unmarshal(message, &in)
if err != nil {
// TODO Place error behind debug/verbose var
log.Println(string(message))
log.Println()
log.Println(err)
c.Close()
return
}
}
in.S = c.ID
c.In <- &in
}
}
func (c *Client) handleWrite() {
var (
out []byte
err error
)
for msg := range c.Out {
if msg == nil {
return
}
out, err = json.Marshal(msg)
if err != nil {
c.Close()
return
}
c.Conn.WriteMessage(1, out)
}
}
func (c *Client) Close() {
if c.Status == -1 {
return
}
c.Status = -1
c.AudioTrack = nil
if c.PeerConn != nil {
c.PeerConn.Close()
}
if c.Conn != nil {
c.Conn.Close()
}
c.In <- nil
c.Out <- nil
// TODO Place behind debug/verbose flag
log.Printf("%+v", errors.New("Closing client #"+strconv.Itoa(c.ID)))
go func() {
c.Terminated <- true
}()
}