Make ready for production

websocket
ALI Hamza 2020-01-31 10:03:02 +07:00
parent 1fa7cfd996
commit 3a3871652e
9 changed files with 233 additions and 111 deletions

@ -19,7 +19,7 @@ func GetAllVisitors() []common.Visitor {
//GetVisitor retrieves the visitor with the specified ID in the form of `common.Visitor`.
func GetVisitor(email string) (common.Visitor, error) {
rows, _ := db.Query("SELECT * FROM clients WHERE email=?", email)
rows, _ := db.Query("SELECT * FROM clients WHERE email=? COLLATE NOCASE", email)
defer rows.Close()
visitors := convertIntoVisitors(rows)
if len(visitors) == 0 {
@ -42,7 +42,7 @@ func NewVisitor(visitor common.Visitor) (bool, common.Visitor) {
//EditVisitor updates the provided visitor with the new name associated with the email.
func EditVisitor(visitor common.Visitor) (bool, common.Visitor) {
result, _ := db.Exec("UPDATE clients SET name=? WHERE email=?", visitor.Name, visitor.Email)
result, _ := db.Exec("UPDATE clients SET name=? WHERE email=? COLLATE NOCASE", visitor.Name, visitor.Email)
rowsAffected, _ := result.RowsAffected()
updated, _ := GetVisitor(visitor.Email)
@ -51,7 +51,7 @@ func EditVisitor(visitor common.Visitor) (bool, common.Visitor) {
//SetFirstTicket updates the first ticket column for the provided visitor
func SetFirstTicket(visitor common.Visitor) bool {
result, _ := db.Exec("UPDATE clients SET first_ticket=? WHERE email=?", visitor.FirstTicket, visitor.Email)
result, _ := db.Exec("UPDATE clients SET first_ticket=? WHERE email=? COLLATE NOCASE", visitor.FirstTicket, visitor.Email)
rowsAffected, _ := result.RowsAffected()
return rowsAffected > 0

@ -3,6 +3,8 @@ module JISQueueing
go 1.12
require (
github.com/go-redis/redis/v7 v7.0.0-beta.5 // indirect
github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.3
github.com/gorilla/websocket v1.4.1
github.com/mattn/go-sqlite3 v1.11.0

@ -1,13 +1,40 @@
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-redis/redis/v7 v7.0.0-beta.5 h1:7bdbDkv2nKZm6Tydrvmay3xOvVaxpAT4ZsNTrSDMZUE=
github.com/go-redis/redis/v7 v7.0.0-beta.5/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
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/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -1,22 +1,29 @@
package main
import (
"JISQueueing/common"
"JISQueueing/server"
"flag"
"log"
"net/http"
"strconv"
)
var hashToStaff = make(map[string]common.Staff)
"github.com/gorilla/handlers"
)
func main() {
var port int
var debug bool
flag.IntVar(&port, "port", 8080, "Specify port for socket and webserver")
flag.IntVar(&port, "port", 443, "Specify port for socket and webserver")
flag.BoolVar(&debug, "debug", false, "Specify the debug mode status")
flag.Parse()
hostLocation := ":" + strconv.Itoa(port)
mux := server.NewServerMux(debug)
http.ListenAndServe(hostLocation, mux)
cors := handlers.CORS(
handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}),
handlers.AllowedMethods([]string{"POST", "OPTIONS"}),
handlers.AllowedOrigins([]string{"*"}),
)(mux)
//log.Fatal(http.ListenAndServe(hostLocation, cors))
log.Fatal(http.ListenAndServeTLS(hostLocation, "server.crt", "server.key", cors))
}

@ -23,10 +23,7 @@ func NewServerMux(debug bool) http.Handler {
router.PathPrefix("/api").Handler(http.HandlerFunc(NotFound))
router.PathPrefix("/assets").Handler(http.FileServer(http.Dir("./static/")))
router.PathPrefix("/css").Handler(http.FileServer(http.Dir("./static/")))
router.PathPrefix("/js").Handler(http.FileServer(http.Dir("./static/")))
router.PathPrefix("/static").Handler(http.FileServer(http.Dir("./static")))
router.PathPrefix("/").HandlerFunc(indexHandler)
return router

@ -1,6 +1,8 @@
package socket
import (
"fmt"
"github.com/gorilla/websocket"
)
@ -8,6 +10,13 @@ var displays = make(map[*websocket.Conn]bool)
func onNewDisplay(who *websocket.Conn) {
displays[who] = true
for _, conn := range onlineStaff {
if conn.Table == -1 {
continue
}
who.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("status %d %d %d", conn.Table, conn.Status, conn.CurrentTicket)))
}
}
func onDisplayMessage(who *websocket.Conn, msg string) {
@ -21,4 +30,4 @@ func sendDisplayMessage(msg string) {
for display := range displays {
display.WriteMessage(websocket.TextMessage, []byte(msg))
}
}
}

@ -9,14 +9,18 @@ import (
"github.com/gorilla/websocket"
)
var tickets = make(map[common.Ticket]bool)
var queue = make([]common.Ticket, 0)
func newTicket(ticket common.Ticket, who *websocket.Conn) {
tickets[ticket] = false
queue = append(queue, ticket)
jsonTicket, _ := json.Marshal(ticket)
sendStaffMessage("new " + string(jsonTicket))
who.WriteMessage(websocket.TextMessage, []byte("success new "+string(jsonTicket)))
for _, conn := range onlineStaff {
if conn.Status == 1 {
notifyTicket(conn.Conn)
}
}
}
func claimedTicket(ticket common.Ticket, staff common.Staff, table int, who *websocket.Conn) {
@ -24,57 +28,71 @@ func claimedTicket(ticket common.Ticket, staff common.Staff, table int, who *web
who.WriteMessage(websocket.TextMessage, []byte("error accept the ticket has already been completed or cancelled"))
return
}
delete(tickets, ticket)
removeTicket(ticket.ID)
ticket.Staff = staff.Username
tickets[ticket] = true
jsonTicket, _ := json.Marshal(ticket)
sendDisplayMessage("claimed " + strconv.Itoa(table) + " " + strconv.Itoa(ticket.ID))
who.WriteMessage(websocket.TextMessage, []byte("success claimed "+string(jsonTicket)))
for conn, s := range connToStaff {
if s.Username != staff.Username {
conn.WriteMessage(websocket.TextMessage, []byte("claimed "+string(jsonTicket)))
for _, conn := range onlineStaff {
if conn.Status == 1 {
conn.Conn.WriteMessage(websocket.TextMessage, []byte("info claimed "+string(jsonTicket)))
notifyTicket(conn.Conn)
}
}
}
func finishedTicket(ticket common.Ticket, id int, table int, who *websocket.Conn) {
delete(tickets, ticket)
func finishedTicket(id int, table int, who *websocket.Conn) {
if success := db.FinishTicket(id); !success {
who.WriteMessage(websocket.TextMessage, []byte("error complete the ticket has already been completed or cancelled"))
return
}
who.WriteMessage(websocket.TextMessage, []byte("success complete "+strconv.Itoa(id)))
notifyTicket(who)
sendDisplayMessage("complete " + strconv.Itoa(table))
}
func cancelTicket(ticket common.Ticket, id int, table int, who *websocket.Conn) {
delete(tickets, ticket)
func cancelTicket(id int, table int, who *websocket.Conn) {
if success := db.CancelTicket(id); !success {
who.WriteMessage(websocket.TextMessage, []byte("error cancel the ticket has already been completed or cancelled"))
return
}
who.WriteMessage(websocket.TextMessage, []byte("success cancel "+strconv.Itoa(id)))
notifyTicket(who)
sendDisplayMessage("cancel " + strconv.Itoa(table))
}
func newStaff(table int, who *websocket.Conn) {
who.WriteMessage(websocket.TextMessage, []byte("success pick "+strconv.Itoa(table)))
for member, num := range connToTable {
if num == -1 {
sendTaken(member)
}
for _, conn := range onlineStaff {
sendTaken(conn.Conn)
}
sendDisplayMessage("pick " + strconv.Itoa(table))
notifyTicket(who)
}
func leaveStaff(table int) {
sendDisplayMessage("unpick " + strconv.Itoa(table))
for member, num := range connToTable {
if num == -1 {
sendTaken(member)
for _, conn := range onlineStaff {
sendTaken(conn.Conn)
}
}
func notifyTicket(who *websocket.Conn) {
if len(queue) == 0 {
return
}
jsonTicket, _ := json.Marshal(queue[0])
who.WriteMessage(websocket.TextMessage, []byte("info new "+string(jsonTicket)))
}
func removeTicket(id int) {
for i, t := range queue {
if id == t.ID {
copy(queue[i:], queue[i+1:])
queue[len(queue)-1] = common.Ticket{}
queue = queue[:len(queue)-1]
return
}
}
}

@ -3,7 +3,6 @@ package socket
import (
"fmt"
"net/http"
"strings"
"github.com/gorilla/websocket"
)
@ -20,7 +19,8 @@ var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return strings.Contains(r.Host, "localhost")
return true
//return strings.Contains(r.Host, "localhost")
},
}

@ -3,131 +3,188 @@ package socket
import (
"JISQueueing/common"
"JISQueueing/db"
"github.com/gorilla/websocket"
"strconv"
"strings"
"github.com/gorilla/websocket"
)
//Receive Commands: [status, pick, accept, complete]
//Send Commands: [new,
var connToTable = make(map[*websocket.Conn]int)
var connToStaff = make(map[*websocket.Conn]common.Staff)
type staffConnection struct {
Conn *websocket.Conn
Staff common.Staff
Table int
Status int
CurrentTicket int
}
var onlineStaff = make(map[*websocket.Conn]staffConnection)
func onNewStaff(who *websocket.Conn) {
connToTable[who] = -1
onlineStaff[who] = staffConnection{
Conn: who,
Staff: common.Staff{
Username: "{}",
},
Table: -1,
Status: 0,
CurrentTicket: -1,
}
sendTaken(who)
}
func onStaffMessage(who *websocket.Conn, msg string) {
message := strings.SplitN(strings.TrimSpace(msg), " ", 2)
switch message[0] {
case "unpick":
if table, ok := connToTable[who]; !ok || table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error unpick you do not have a table assigned"))
return
}
connToTable[who] = -1
delete(connToStaff, who)
who.WriteMessage(websocket.TextMessage, []byte("success unpick"))
leaveStaff(connToTable[who])
case "accept":
id, err := strconv.Atoi(strings.TrimSpace(message[1]))
conn, ok := onlineStaff[who]
case "pick":
args := strings.SplitN(msg, " ", 3)
if len(args) < 3 {
if err != nil || !ok {
return
}
choice, err := strconv.Atoi(strings.TrimSpace(args[1]))
if err != nil {
if conn.Staff.Username == "{}" || conn.Status == 0 {
who.WriteMessage(websocket.TextMessage, []byte("error accept your session token was found to be invalid. please relogin"))
return
}
if conn.Table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error accept you do not have a table chosen"))
}
staff, err := db.GetTokenOwner(strings.TrimSpace(args[2]))
if err == db.ErrTokenNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error pick "+err.Error()))
ticket, err := db.GetTicket(id)
if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error accept "+err.Error()))
return
}
if isTaken(choice) {
who.WriteMessage(websocket.TextMessage, []byte("error the chosen table is not available"))
if ticket.Staff != "{}" {
who.WriteMessage(websocket.TextMessage, []byte("error accept this ticket is already claimed"))
return
}
connToStaff[who] = staff
connToTable[who] = choice
newStaff(choice, who)
conn.Status = 2
conn.CurrentTicket = id
onlineStaff[who] = conn
claimedTicket(ticket, conn.Staff, conn.Table, who)
case "accept":
case "cancel":
id, err := strconv.Atoi(strings.TrimSpace(message[1]))
if err != nil {
return
}
conn, ok := onlineStaff[who]
staff, ok := connToStaff[who]
if !ok {
who.WriteMessage(websocket.TextMessage, []byte("error accept your session token was found to be invalid. please relogin"))
if err != nil || !ok {
return
}
if connToTable[who] == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error accept you do not have a table chosen"))
}
ticket, err := db.GetTicket(id)
if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error accept "+err.Error()))
who.WriteMessage(websocket.TextMessage, []byte("error cancel "+err.Error()))
return
}
if ticket.Staff != "{}" {
who.WriteMessage(websocket.TextMessage, []byte("error accept this ticket is already claimed"))
if conn.Staff.Username != ticket.Staff {
who.WriteMessage(websocket.TextMessage, []byte("error cancel you do not own this ticket"))
return
}
claimedTicket(ticket, staff, connToTable[who], who)
conn.Status = 1
conn.CurrentTicket = -1
onlineStaff[who] = conn
cancelTicket(id, conn.Table, who)
case "complete":
id, err := strconv.Atoi(strings.TrimSpace(message[1]))
staff := connToStaff[who]
table, ok := connToTable[who]
conn, ok := onlineStaff[who]
if err != nil {
if err != nil || !ok {
return
}
if !ok {
who.WriteMessage(websocket.TextMessage, []byte("error complete you are not assigned to any table"))
}
ticket, err := db.GetTicket(id)
if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error complete "+err.Error()))
return
}
if staff.Username != ticket.Staff {
if conn.Staff.Username != ticket.Staff {
who.WriteMessage(websocket.TextMessage, []byte("error complete you do not own this ticket"))
return
}
finishedTicket(ticket, id, table, who)
case "cancel":
id, err := strconv.Atoi(strings.TrimSpace(message[1]))
staff := connToStaff[who]
table, ok := connToTable[who]
conn.Status = 1
conn.CurrentTicket = -1
onlineStaff[who] = conn
finishedTicket(id, conn.Table, who)
case "pick":
args := strings.SplitN(msg, " ", 3)
if len(args) < 3 {
return
}
choice, err := strconv.Atoi(strings.TrimSpace(args[1]))
if err != nil {
return
}
if !ok {
who.WriteMessage(websocket.TextMessage, []byte("error cancel you are not assigned to any table"))
staff, err := db.GetTokenOwner(strings.TrimSpace(args[2]))
if err == db.ErrTokenNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error pick "+err.Error()))
return
}
if isTaken(choice) {
who.WriteMessage(websocket.TextMessage, []byte("error the chosen table is not available"))
return
}
if onlineStaff[who].Table != -1 {
leaveStaff(onlineStaff[who].Table)
}
ticket, err := db.GetTicket(id)
if err == db.ErrTicketNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error cancel "+err.Error()))
onlineStaff[who] = staffConnection{
Conn: who,
Staff: staff,
Table: choice,
Status: 1,
CurrentTicket: -1,
}
newStaff(choice, who)
case "status":
if conn, ok := onlineStaff[who]; !ok || conn.Table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error unpick you do not have a table assigned"))
return
}
if staff.Username != ticket.Staff {
who.WriteMessage(websocket.TextMessage, []byte("error cancel you do not own this ticket"))
notifyTicket(who)
case "unpick":
conn, ok := onlineStaff[who]
if !ok || conn.Table == -1 {
who.WriteMessage(websocket.TextMessage, []byte("error unpick you do not have a table assigned"))
return
}
cancelTicket(ticket, id, table, who)
table := conn.Table
conn.Table = -1
conn.Status = 0
staff := conn.Staff
staff.Username = "{}"
conn.Staff = staff
onlineStaff[who] = conn
leaveStaff(table)
who.WriteMessage(websocket.TextMessage, []byte("success unpick"))
case "valid":
if len(message) < 2 {
return
}
_, err := db.GetTokenOwner(strings.TrimSpace(message[1]))
if err == db.ErrTokenNotFound {
who.WriteMessage(websocket.TextMessage, []byte("error valid "+err.Error()))
return
}
who.WriteMessage(websocket.TextMessage, []byte("success valid"))
default:
who.WriteMessage(websocket.TextMessage, []byte("error "+message[0]+" not found"))
@ -135,8 +192,8 @@ func onStaffMessage(who *websocket.Conn, msg string) {
}
func sendStaffMessage(msg string) {
for who, num := range connToTable {
if num == -1 {
for who, conn := range onlineStaff {
if conn.Table == -1 {
continue
}
who.WriteMessage(websocket.TextMessage, []byte(msg))
@ -144,33 +201,38 @@ func sendStaffMessage(msg string) {
}
func onStaffDisconnect(who *websocket.Conn) {
num, ok := connToTable[who]
delete(connToTable, who)
delete(connToStaff, who)
if ok && num != -1 {
leaveStaff(connToTable[who])
conn, ok := onlineStaff[who]
if !ok || conn.Table == -1 {
return
}
if conn.Status == 2 {
cancelTicket(conn.CurrentTicket, conn.Table, who)
}
delete(onlineStaff, who)
leaveStaff(conn.Table)
}
func sendTaken(who *websocket.Conn) {
var taken = ""
for _, num := range connToTable {
if num != -1 {
taken = taken + " " + strconv.Itoa(num)
for _, conn := range onlineStaff {
if conn.Table != -1 {
taken = taken + " " + strconv.Itoa(conn.Table)
}
}
if taken != "" {
who.WriteMessage(websocket.TextMessage, []byte("taken"+taken))
who.WriteMessage(websocket.TextMessage, []byte("info taken"+taken))
} else {
who.WriteMessage(websocket.TextMessage, []byte("info taken"))
}
}
func isTaken(table int) bool {
if table < 0 {
if table < 1 || table > 5 {
return true
}
for _, num := range connToTable {
if table == num {
for _, conn := range onlineStaff {
if table == conn.Table {
return true
}
}