Make a chat room with gorilla websocket

Keywords: Go socket Unix JSON

This demo implements:

  1. Message broadcasting
  2. Heartbeat detection

Chat via command line

The specific logic is in websocket.go

The core here is the global variable aliveList, which is responsible for distributing messages to clients. Events are passed through channel s to reduce blocking

A single link will be registered in the Livelist, and ConnList is all the active links

// Livelist current online list
type AliveList struct {
    ConnList  map[string]*Client
    register  chan *Client
    destroy   chan *Client
    broadcast chan Message
    cancel    chan int
    Len       int
}

// Client socket client
type Client struct {
    ID     string
    conn   *websocket.Conn
    cancel chan int
}

An event listening cycle will be executed after the service is started

// lsnrctl start
func (al *AliveList) run() {
    log.Println("Start listening for registration events")
    for {
        select {
        case client := <-al.register:
            log.Println("Registration event:", client.ID)
            al.ConnList[client.ID] = client
            al.Len++
            al.SysBroadcast(ConnectedMessage, Message{
                ID:      client.ID,
                Content: "connected",
                SentAt:  time.Now().Unix(),
            })

        case client := <-al.destroy:
            log.Println("Destruction event:", client.ID)
            err := client.conn.Close()
            if err != nil {
                log.Printf("destroy Error: %v \n", err)
            }
            delete(al.ConnList, client.ID)
            al.Len--

        case message := <-al.broadcast:
            log.Printf("Broadcast events: %s %s %d \n", message.ID, message.Content, message.Type)
            for id := range al.ConnList {
                if id != message.ID {

                    err := al.sendMessage(id, message)
                    if err != nil {
                        log.Println("broadcastError: ", err)
                    }
                }
            }

        case sign := <-al.cancel:
            log.Println("Termination event: ", sign)
            os.Exit(0)
        }
    }
}

Because there are many types of messages, and the simple string cannot meet the requirements, the commonly used json format is selected for delivery. At present, the messages are divided into:

const (
    // SystemMessage system message
    SystemMessage = iota
    // BroadcastMessage broadcast message (normal message)
    BroadcastMessage
    // HeartBeatMessage
    HeartBeatMessage
    // ConnectedMessage Launch Notification
    ConnectedMessage
    // Disconnect edmessage offline notification
    DisconnectedMessage
)



// Message body structure
type Message struct {
    ID      string
    Content string
    SentAt  int64
    Type    int     // < systemmessage and other types are here
}

If you have free time, make more chat rooms and optimize the current event cycle logic
If you have more spare power, do a better client?

demo address
My blog

Posted by coderage on Sun, 01 Dec 2019 05:49:22 -0800