From 5516313c7962d4617bfba706f624cf1462f73165 Mon Sep 17 00:00:00 2001 From: joeyak Date: Wed, 13 Mar 2019 16:47:19 -0400 Subject: [PATCH] Allow chat to be sent before the name is sent to the server closes #17 --- chatclient.go | 8 ++++++-- chatroom.go | 46 ++++++++++++++++++++++++++++++++++++++++------ handlers.go | 14 ++++++++++++-- main.go | 3 ++- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/chatclient.go b/chatclient.go index 26b4e4f..a36fd0e 100644 --- a/chatclient.go +++ b/chatclient.go @@ -11,6 +11,10 @@ import ( "github.com/zorchenhimer/MovieNight/common" ) +func connSend(s string, c *websocket.Conn) { + c.WriteMessage(websocket.TextMessage, []byte(s)) +} + type Client struct { name string // Display name conn *websocket.Conn @@ -108,8 +112,8 @@ func (cl *Client) Exit() { } //Sending message block to the client -func (cl *Client) Send(msgs string) { - cl.conn.WriteMessage(websocket.TextMessage, []byte(msgs)) +func (cl *Client) Send(s string) { + connSend(s, cl.conn) } // Send server message to this client diff --git a/chatroom.go b/chatroom.go index af0e5e4..14b8395 100644 --- a/chatroom.go +++ b/chatroom.go @@ -1,8 +1,11 @@ package main import ( + "errors" "fmt" + uuid "github.com/satori/go.uuid" + "math/rand" "path/filepath" "regexp" @@ -24,19 +27,23 @@ var re_username *regexp.Regexp = regexp.MustCompile(`^[0-9a-zA-Z_-]+$`) type ChatRoom struct { clients map[string]*Client // this needs to be a pointer. clientsMtx sync.Mutex + tempConn map[string]*websocket.Conn queue chan string playing string playingLink string } //initializing the chatroom -func (cr *ChatRoom) Init() error { - cr.queue = make(chan string, 5) - cr.clients = make(map[string]*Client) +func newChatRoom() (*ChatRoom, error) { + cr := &ChatRoom{ + queue: make(chan string, 5), + clients: make(map[string]*Client), + tempConn: make(map[string]*websocket.Conn), + } num, err := LoadEmotes() if err != nil { - return fmt.Errorf("Error loading emotes: %s", err) + return nil, fmt.Errorf("Error loading emotes: %s", err) } fmt.Printf("Loaded %d emotes\n", num) @@ -47,7 +54,7 @@ func (cr *ChatRoom) Init() error { time.Sleep(100 * time.Millisecond) } }() - return nil + return cr, nil } func LoadEmotes() (int, error) { @@ -87,9 +94,32 @@ func randomColor() string { nums[3], nums[4], nums[5]) } +func (cr *ChatRoom) JoinTemp(conn *websocket.Conn) (string, error) { + if conn == nil { + return "", errors.New("conn should not be nil") + } + + uid, err := uuid.NewV4() + if err != nil { + return "", fmt.Errorf("could not create uuid, %v", err) + } + + suid := uid.String() + if _, ok := cr.tempConn[suid]; ok { + return "", errors.New("%#v is already in the temp connections") + } + + cr.tempConn[suid] = conn + return suid, nil +} + //registering a new client //returns pointer to a Client, or Nil, if the name is already taken -func (cr *ChatRoom) Join(name string, conn *websocket.Conn) (*Client, error) { +func (cr *ChatRoom) Join(name, uid string) (*Client, error) { + conn, hasConn := cr.tempConn[uid] + if !hasConn { + return nil, errors.New("connection is missing from temp connections") + } if len(name) < UsernameMinLength || len(name) > UsernameMaxLength || !re_username.MatchString(name) { return nil, UserFormatError{Name: name} @@ -115,6 +145,7 @@ func (cr *ChatRoom) Join(name string, conn *websocket.Conn) (*Client, error) { } cr.clients[strings.ToLower(name)] = client + delete(cr.tempConn, uid) fmt.Printf("[join] %s %s\n", host, name) //client.Send(cr.GetPlayingString()) @@ -329,6 +360,9 @@ infLoop: for _, client := range cr.clients { client.Send(msgBlock) } + for _, conn := range cr.tempConn { + connSend(msgBlock, conn) + } } } diff --git a/handlers.go b/handlers.go index 93b1337..e06a22f 100644 --- a/handlers.go +++ b/handlers.go @@ -18,7 +18,7 @@ import ( var ( //global variable for handling all chat traffic - chat ChatRoom + chat *ChatRoom // Read/Write mutex for rtmp stream l = &sync.RWMutex{} @@ -97,6 +97,12 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { go func() { var client *Client + uid, err := chat.JoinTemp(conn) + if err != nil { + fmt.Printf("[handler] could not do a temp join, %v\n", err) + conn.Close() + } + //first message has to be the name // loop through name since websocket is opened once for client == nil { @@ -108,7 +114,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { } name := string(msg) - client, err = chat.Join(name, conn) + client, err = chat.Join(name, uid) if err != nil { switch err.(type) { case UserFormatError, UserTakenError: @@ -117,6 +123,10 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { fmt.Printf("[BAN] %v\n", err) // close connection since banned users shouldn't be connecting conn.Close() + default: + // for now all errors not caught need to be warned + fmt.Printf("[handler] %v\n", err) + conn.Close() } } } diff --git a/main.go b/main.go index b5a9b1d..edd834f 100644 --- a/main.go +++ b/main.go @@ -50,7 +50,8 @@ func main() { } // Load emotes before starting server. - if err := chat.Init(); err != nil { + var err error + if chat, err = newChatRoom(); err != nil { fmt.Println(err) os.Exit(1) }