Remove temp connections
Temp connections were removed to reduce some complexity. Now a connection is a full client, even before joining chat. A name is required to be set to join chat and receive messages. This change also removes the need for UUIDs on connections and clients.
This commit is contained in:
parent
0c3850d2f7
commit
d513fe872d
@ -172,6 +172,12 @@ func (cl *Client) NewMsg(data common.ClientData) {
|
||||
}
|
||||
|
||||
func (cl *Client) SendChatData(data common.ChatData) error {
|
||||
// Don't send chat or event data to clients that have not fully joined the
|
||||
// chatroom (ie, they have not set a name).
|
||||
if cl.name == "" && (data.Type == common.DTChat || data.Type == common.DTEvent) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Colorize name on chat messages
|
||||
if data.Type == common.DTChat {
|
||||
var err error
|
||||
|
@ -491,13 +491,8 @@ var commands = &CommandControl{
|
||||
Function: func(cl *Client, args []string) (string, error) {
|
||||
cl.belongsTo.clientsMtx.Lock()
|
||||
common.LogInfoln("Clients:")
|
||||
for uuid, client := range cl.belongsTo.clients {
|
||||
common.LogInfof(" [%s] %s %s\n", uuid, client.name, client.conn.Host())
|
||||
}
|
||||
|
||||
common.LogInfoln("TmpConn:")
|
||||
for uuid, conn := range cl.belongsTo.tempConn {
|
||||
common.LogInfof(" [%s] %s\n", uuid, conn.Host())
|
||||
for id, client := range cl.belongsTo.clients {
|
||||
common.LogInfof(" [%d] %s %s\n", id, client.name, client.conn.Host())
|
||||
}
|
||||
cl.belongsTo.clientsMtx.Unlock()
|
||||
return "see console for output", nil
|
||||
|
100
chatroom.go
100
chatroom.go
@ -1,11 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@ -18,9 +15,8 @@ const (
|
||||
)
|
||||
|
||||
type ChatRoom struct {
|
||||
clients map[string]*Client // this needs to be a pointer. key is suid.
|
||||
clients []*Client // this needs to be a pointer. key is suid.
|
||||
clientsMtx sync.Mutex
|
||||
tempConn map[string]*chatConnection
|
||||
|
||||
queue chan common.ChatData
|
||||
modqueue chan common.ChatData // mod and admin broadcast messages
|
||||
@ -37,8 +33,7 @@ func newChatRoom() (*ChatRoom, error) {
|
||||
cr := &ChatRoom{
|
||||
queue: make(chan common.ChatData, 1000),
|
||||
modqueue: make(chan common.ChatData, 1000),
|
||||
clients: make(map[string]*Client),
|
||||
tempConn: make(map[string]*chatConnection),
|
||||
clients: []*Client{},
|
||||
}
|
||||
|
||||
num, err := common.LoadEmotes()
|
||||
@ -52,39 +47,11 @@ func newChatRoom() (*ChatRoom, error) {
|
||||
return cr, nil
|
||||
}
|
||||
|
||||
func (cr *ChatRoom) JoinTemp(conn *chatConnection) (string, error) {
|
||||
// A new client joined
|
||||
func (cr *ChatRoom) Join(conn *chatConnection, data common.JoinData) (*Client, error) {
|
||||
defer cr.clientsMtx.Unlock()
|
||||
cr.clientsMtx.Lock()
|
||||
|
||||
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 "", fmt.Errorf("%#v is already in the temp connections", suid)
|
||||
}
|
||||
|
||||
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(uid string, data common.JoinData) (*Client, error) {
|
||||
defer cr.clientsMtx.Unlock()
|
||||
cr.clientsMtx.Lock()
|
||||
|
||||
conn, hasConn := cr.tempConn[uid]
|
||||
if !hasConn {
|
||||
return nil, errors.New("connection is missing from temp connections")
|
||||
}
|
||||
|
||||
sendHiddenMessage := func(cd common.ClientDataType, i interface{}) {
|
||||
// If the message cant be converted, then just don't send
|
||||
if d, err := common.NewChatHiddenMessage(cd, i).ToJSON(); err == nil {
|
||||
@ -128,8 +95,7 @@ func (cr *ChatRoom) Join(uid string, data common.JoinData) (*Client, error) {
|
||||
return nil, newBannedUserError(host, data.Name, names)
|
||||
}
|
||||
|
||||
cr.clients[uid] = client
|
||||
delete(cr.tempConn, uid)
|
||||
cr.clients = append(cr.clients, client)
|
||||
|
||||
common.LogChatf("[join] %s %s\n", host, data.Color)
|
||||
playingCommand, err := common.NewChatCommand(common.CmdPlaying, []string{cr.playing, cr.playingLink}).ToJSON()
|
||||
@ -152,7 +118,7 @@ func (cr *ChatRoom) Leave(name, color string) {
|
||||
defer cr.clientsMtx.Unlock()
|
||||
cr.clientsMtx.Lock() //preventing simultaneous access to the `clients` map
|
||||
|
||||
client, suid, err := cr.getClient(name)
|
||||
client, id, err := cr.getClient(name)
|
||||
if err != nil {
|
||||
common.LogErrorf("[leave] Unable to get client suid %v\n", err)
|
||||
return
|
||||
@ -160,7 +126,7 @@ func (cr *ChatRoom) Leave(name, color string) {
|
||||
host := client.Host()
|
||||
name = client.name // grab the name from here for proper capitalization
|
||||
client.conn.Close()
|
||||
cr.delClient(suid)
|
||||
cr.delClient(id)
|
||||
|
||||
cr.AddEventMsg(common.EvLeave, name, color)
|
||||
common.LogChatf("[leave] %s %s\n", host, name)
|
||||
@ -171,7 +137,7 @@ func (cr *ChatRoom) Kick(name string) error {
|
||||
defer cr.clientsMtx.Unlock()
|
||||
cr.clientsMtx.Lock() //preventing simultaneous access to the `clients` map
|
||||
|
||||
client, suid, err := cr.getClient(name)
|
||||
client, id, err := cr.getClient(name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to get client for name " + name)
|
||||
}
|
||||
@ -187,7 +153,7 @@ func (cr *ChatRoom) Kick(name string) error {
|
||||
color := client.color
|
||||
host := client.Host()
|
||||
client.conn.Close()
|
||||
cr.delClient(suid)
|
||||
cr.delClient(id)
|
||||
|
||||
cr.AddEventMsg(common.EvKick, name, color)
|
||||
common.LogInfof("[kick] %s %s has been kicked\n", host, name)
|
||||
@ -198,7 +164,7 @@ func (cr *ChatRoom) Ban(name string) error {
|
||||
defer cr.clientsMtx.Unlock()
|
||||
cr.clientsMtx.Lock()
|
||||
|
||||
client, suid, err := cr.getClient(name)
|
||||
client, id, err := cr.getClient(name)
|
||||
if err != nil {
|
||||
common.LogErrorf("[ban] Unable to get client for name %q\n", name)
|
||||
return fmt.Errorf("Cannot find that name")
|
||||
@ -212,14 +178,16 @@ func (cr *ChatRoom) Ban(name string) error {
|
||||
host := client.Host()
|
||||
color := client.color
|
||||
|
||||
// Remove the named client
|
||||
client.conn.Close()
|
||||
cr.delClient(suid)
|
||||
cr.delClient(id)
|
||||
|
||||
for suid, c := range cr.clients {
|
||||
// Remove additional clients on that IP address
|
||||
for id, c := range cr.clients {
|
||||
if c.Host() == host {
|
||||
names = append(names, client.name)
|
||||
client.conn.Close()
|
||||
cr.delClient(suid)
|
||||
cr.delClient(id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,32 +316,6 @@ func (cr *ChatRoom) Broadcast() {
|
||||
for _, client := range cr.clients {
|
||||
go send(msg, client)
|
||||
}
|
||||
|
||||
// Only send Chat and Event stuff to temp clients
|
||||
if msg.Type != common.DTChat && msg.Type != common.DTEvent {
|
||||
// Put this here instead of having two lock/unlock blocks. We want
|
||||
// to avoid a case where a client is removed from the temp users
|
||||
// and added to the clients between the two blocks.
|
||||
cr.clientsMtx.Unlock()
|
||||
break
|
||||
}
|
||||
|
||||
data, err := msg.ToJSON()
|
||||
if err != nil {
|
||||
common.LogErrorf("Error converting ChatData to ChatDataJSON: %v\n", err)
|
||||
cr.clientsMtx.Unlock()
|
||||
break
|
||||
}
|
||||
|
||||
for uuid, conn := range cr.tempConn {
|
||||
go func(c *chatConnection, suid string) {
|
||||
err = c.WriteData(data)
|
||||
if err != nil {
|
||||
common.LogErrorf("Error writing data to connection: %v\n", err)
|
||||
delete(cr.tempConn, suid)
|
||||
}
|
||||
}(conn, uuid)
|
||||
}
|
||||
cr.clientsMtx.Unlock()
|
||||
case msg := <-cr.modqueue:
|
||||
cr.clientsMtx.Lock()
|
||||
@ -416,18 +358,18 @@ func (cr *ChatRoom) GetNames() []string {
|
||||
return names
|
||||
}
|
||||
|
||||
func (cr *ChatRoom) delClient(suid string) {
|
||||
delete(cr.clients, strings.ToLower(suid))
|
||||
func (cr *ChatRoom) delClient(sliceId int) {
|
||||
cr.clients = append(cr.clients[:sliceId], cr.clients[sliceId+1:]...)
|
||||
}
|
||||
|
||||
func (cr *ChatRoom) getClient(name string) (*Client, string, error) {
|
||||
for suid, client := range cr.clients {
|
||||
func (cr *ChatRoom) getClient(name string) (*Client, int, error) {
|
||||
for id, client := range cr.clients {
|
||||
if client.name == name {
|
||||
return client, suid, nil
|
||||
return client, id, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", fmt.Errorf("client with that name not found")
|
||||
return nil, -1, fmt.Errorf("client with that name not found")
|
||||
}
|
||||
|
||||
func (cr *ChatRoom) generateModPass() string {
|
||||
|
3
go.mod
3
go.mod
@ -7,9 +7,6 @@ require (
|
||||
github.com/dennwc/dom v0.3.0
|
||||
github.com/gorilla/sessions v1.1.3
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.0.1
|
||||
github.com/nareix/joy4 v0.0.0-20181022032202-3ddbc8f9d431
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
)
|
||||
|
9
go.sum
9
go.sum
@ -42,11 +42,6 @@ github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307 h1:vl4eIlySbjertFaNwiM
|
||||
github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307/go.mod h1:BjPj+aVjl9FW/cCGiF3nGh5v+9Gd3VCgBQbod/GlMaQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lucasb-eyer/go-colorful v1.0.1 h1:nKJRBvZWPzvkwB4sY8A3U4zgqLf2Y9c02yzPsbXu/5c=
|
||||
@ -68,8 +63,6 @@ github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM=
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@ -88,7 +81,5 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8 h1:YoY1wS6JYVRpIfFngRf2HHo9R
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
|
15
handlers.go
15
handlers.go
@ -99,6 +99,8 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
common.LogDebugln("Connection has been upgraded to websocket")
|
||||
|
||||
chatConn := &chatConnection{
|
||||
Conn: conn,
|
||||
// If the server is behind a reverse proxy (eg, Nginx), look
|
||||
@ -109,14 +111,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
go func() {
|
||||
var client *Client
|
||||
|
||||
uid, err := chat.JoinTemp(chatConn)
|
||||
if err != nil {
|
||||
common.LogErrorf("[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
|
||||
// Get the client object
|
||||
for client == nil {
|
||||
var data common.ClientData
|
||||
err := chatConn.ReadData(&data)
|
||||
@ -134,7 +129,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
continue
|
||||
}
|
||||
|
||||
client, err = chat.Join(uid, joinData)
|
||||
client, err = chat.Join(chatConn, joinData)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case UserFormatError, UserTakenError:
|
||||
@ -151,7 +146,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
//then watch for incoming messages
|
||||
// Handle incomming messages
|
||||
for {
|
||||
var data common.ClientData
|
||||
err := conn.ReadJSON(&data)
|
||||
|
Loading…
Reference in New Issue
Block a user