diff --git a/core/chat/client.go b/core/chat/client.go index 2c5553047..de37c4a58 100644 --- a/core/chat/client.go +++ b/core/chat/client.go @@ -1,6 +1,7 @@ package chat import ( + "encoding/json" "fmt" "io" "time" @@ -21,14 +22,23 @@ type Client struct { ConnectedAt time.Time MessageCount int - id string - ws *websocket.Conn - ch chan models.ChatMessage - pingch chan models.PingMessage + clientID string // How we identify unique viewers when counting viewer counts. + socketID string // How we identify a single websocket client. + ws *websocket.Conn + ch chan models.ChatMessage + pingch chan models.PingMessage + usernameChangeChannel chan models.NameChangeEvent doneCh chan bool } +const ( + CHAT = "CHAT" + NAMECHANGE = "NAME_CHANGE" + PING = "PING" + PONG = "PONG" +) + //NewClient creates a new chat client func NewClient(ws *websocket.Conn) *Client { if ws == nil { @@ -38,9 +48,12 @@ func NewClient(ws *websocket.Conn) *Client { ch := make(chan models.ChatMessage, channelBufSize) doneCh := make(chan bool) pingch := make(chan models.PingMessage) - clientID := utils.GenerateClientIDFromRequest(ws.Request()) + usernameChangeChannel := make(chan models.NameChangeEvent) - return &Client{time.Now(), 0, clientID, ws, ch, pingch, doneCh} + clientID := utils.GenerateClientIDFromRequest(ws.Request()) + socketID, _ := shortid.Generate() + + return &Client{time.Now(), 0, clientID, socketID, ws, ch, pingch, usernameChangeChannel, doneCh} } //GetConnection gets the connection for the client @@ -53,7 +66,7 @@ func (c *Client) Write(msg models.ChatMessage) { case c.ch <- msg: default: _server.remove(c) - _server.err(fmt.Errorf("client %s is disconnected", c.id)) + _server.err(fmt.Errorf("client %s is disconnected", c.clientID)) } } @@ -79,7 +92,8 @@ func (c *Client) listenWrite() { case msg := <-c.ch: // log.Println("Send:", msg) websocket.JSON.Send(c.ws, msg) - + case msg := <-c.usernameChangeChannel: + websocket.JSON.Send(c.ws, msg) // receive done request case <-c.doneCh: _server.remove(c) @@ -102,28 +116,59 @@ func (c *Client) listenRead() { // read data from websocket connection default: - var msg models.ChatMessage - id, err := shortid.Generate() + var data []byte + err := websocket.Message.Receive(c.ws, &data) if err != nil { - log.Panicln(err) + if err == io.EOF { + c.doneCh <- true + } else { + log.Errorln(err) + } + return } - msg.ID = id - msg.MessageType = "CHAT" - msg.Timestamp = time.Now() - msg.Visible = true + var messageTypeCheck map[string]interface{} + err = json.Unmarshal(data, &messageTypeCheck) + if err != nil { + log.Errorln(err) + } - if err := websocket.JSON.Receive(c.ws, &msg); err == io.EOF { - c.doneCh <- true - return - } else if err != nil { - _server.err(err) - } else { - c.MessageCount++ + messageType := messageTypeCheck["type"] - msg.ClientID = c.id - _server.SendToAll(msg) + if messageType == CHAT { + c.chatMessageReceived(data) + } else if messageType == NAMECHANGE { + c.userChangedName(data) } } } } + +func (c *Client) userChangedName(data []byte) { + var msg models.NameChangeEvent + err := json.Unmarshal(data, &msg) + if err != nil { + log.Errorln(err) + } + msg.Type = NAMECHANGE + msg.ID = shortid.MustGenerate() + _server.usernameChanged(msg) +} + +func (c *Client) chatMessageReceived(data []byte) { + var msg models.ChatMessage + err := json.Unmarshal(data, &msg) + if err != nil { + log.Errorln(err) + } + + id, _ := shortid.Generate() + msg.ID = id + msg.Timestamp = time.Now() + msg.Visible = true + + c.MessageCount++ + + msg.ClientID = c.clientID + _server.SendToAll(msg) +} diff --git a/core/chat/server.go b/core/chat/server.go index 14cdfe5ca..372a7aa23 100644 --- a/core/chat/server.go +++ b/core/chat/server.go @@ -64,17 +64,23 @@ func (s *server) sendAll(msg models.ChatMessage) { } func (s *server) ping() { - ping := models.PingMessage{MessageType: "PING"} + ping := models.PingMessage{MessageType: PING} for _, c := range s.Clients { c.pingch <- ping } } +func (s *server) usernameChanged(msg models.NameChangeEvent) { + for _, c := range s.Clients { + c.usernameChangeChannel <- msg + } +} + func (s *server) onConnection(ws *websocket.Conn) { client := NewClient(ws) defer func() { - log.Tracef("The client was connected for %s and sent %d messages (%s)", time.Since(client.ConnectedAt), client.MessageCount, client.id) + log.Tracef("The client was connected for %s and sent %d messages (%s)", time.Since(client.ConnectedAt), client.MessageCount, client.clientID) if err := ws.Close(); err != nil { s.errCh <- err @@ -96,15 +102,14 @@ func (s *server) Listen() { select { // add new a client case c := <-s.addCh: - s.Clients[c.id] = c - - s.listener.ClientAdded(c.id) + s.Clients[c.socketID] = c + s.listener.ClientAdded(c.clientID) s.sendWelcomeMessageToClient(c) // remove a client case c := <-s.delCh: - delete(s.Clients, c.id) - s.listener.ClientRemoved(c.id) + delete(s.Clients, c.socketID) + s.listener.ClientRemoved(c.clientID) // broadcast a message to all clients case msg := <-s.sendAllCh: diff --git a/models/nameChangeEvent.go b/models/nameChangeEvent.go new file mode 100644 index 000000000..a08cdb8e0 --- /dev/null +++ b/models/nameChangeEvent.go @@ -0,0 +1,10 @@ +package models + +//NameChangeEvent represents a user changing their name in chat +type NameChangeEvent struct { + OldName string `json:"oldName"` + NewName string `json:"newName"` + Image string `json:"image"` + Type string `json:"type"` + ID string `json:"id"` +} diff --git a/scripts/build.sh b/scripts/build.sh index 3f4571ee5..36f3fd5d0 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -17,7 +17,7 @@ fi [[ -z "${VERSION}" ]] && VERSION='unknownver' || VERSION="${VERSION}" GIT_COMMIT=$(git rev-list -1 HEAD) - +GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) # Change to the root directory of the repository cd $(git rev-parse --show-toplevel) @@ -35,7 +35,7 @@ build() { VERSION=$4 GIT_COMMIT=$5 - echo "Building ${NAME} (${OS}/${ARCH}) release..." + echo "Building ${NAME} (${OS}/${ARCH}) release from ${GIT_BRANCH}..." mkdir -p dist/${NAME} mkdir -p dist/${NAME}/webroot/static @@ -51,7 +51,7 @@ build() { pushd dist/${NAME} >> /dev/null - CGO_ENABLED=1 ~/go/bin/xgo -ldflags "-s -w -X main.GitCommit=${GIT_COMMIT} -X main.BuildVersion=${VERSION} -X main.BuildType=${NAME}" -targets "${OS}/${ARCH}" github.com/gabek/owncast + CGO_ENABLED=1 ~/go/bin/xgo --branch ${GIT_BRANCH} -ldflags "-s -w -X main.GitCommit=${GIT_COMMIT} -X main.BuildVersion=${VERSION} -X main.BuildType=${NAME}" -targets "${OS}/${ARCH}" github.com/gabek/owncast mv owncast-*-${ARCH} owncast zip -r -q -8 ../owncast-$NAME-$VERSION.zip . diff --git a/webroot/index.html b/webroot/index.html index 7ca048362..a7e356dd4 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -123,7 +123,8 @@
-
+ +

+ + +
+ +
+ {{ message.oldName }} is now known as {{ message.newName }}. +
+
+
@@ -166,12 +180,12 @@
- - + + - +