美文网首页
[实战]基于Go实现Web聊天室(3种方式)

[实战]基于Go实现Web聊天室(3种方式)

作者: vouv | 来源:发表于2017-11-03 14:38 被阅读0次

目前实现web聊天室的方式主要有三种:

  • Refresh 刷新

  • Long Polling 长轮询

  • WebSocket 长连接

本文将基于Go语言实现一个web聊天室demo。

后端框架

  • gin
  • gorilla/websocket

下面是效果图

首页

index.jpg

聊天页

image.png

Core 核心实现

我们要实现的是一个订阅,推送的聊天室模型。聊天室需要维护一个用户列表,把每条消息都推送给聊天室内的用户,这里的难点是并发控制。

这里需要对用户加入、用户离开、聊天室广播消息等事件采取并发控制。本项目通过 Go Channel 和 select 语法实现。用户加入聊天室后,服务端为用户开启一个订阅通道,并把用户通道统一存储在聊天室的用户列表里。聊天室里有一个推送通道,每个用户通过这个推送通道向聊天室推送消息。一个聊天室里同一时刻上述事件只允许一个在执行。

用户

  • 订阅通道
  • 推送通道
  • 退出通道

当用户向消息频道发送聊天消息(也可以是登录登出等各种消息)服务器收到后就会向频道用户列表里的所有订阅通道推送这条消息,这就实现了聊天室的功能。

代码

// 处理聊天室中的事件
func (r *Room) Serve() {
    for {
        select {
        // 用户加入房间
        case ch := <-r.joinChn:
            chE := make(chan Event, chanSize)
            r.userCount++
            r.idx++
            r.users[r.idx] = chE
            ch <- Subscription{
                id:    r.idx,
                Pipe:  chE,
                emit:  r.publishChn,
                leave: r.leaveChn,
            }
        case arch := <-r.archiveChan:
            events := []Event{}
            //历史事件
            for e := r.archive.Front(); e != nil; e = e.Next() {
                events = append(events, e.Value.(Event))
            }
            arch <- events
        // 有新的消息
        case event := <-r.publishChn:
            // 推送给所有用户
            for _, v := range r.users {
                v <- event
            }
            // 推送消息后,限制本地只保存指定条历史消息
            if r.archive.Len() >= archiveSize {
                r.archive.Remove(r.archive.Front())
            }
            r.archive.PushBack(event)
        // 用户退出房间
        case k := <-r.leaveChn:
            if _, ok := r.users[k]; ok {
                delete(r.users, k)
                r.userCount--
            }
        }
    }
}


前端框架

前端采用目前比较流行的技术

  • Vuejs + ElementUI
  • js-cookie

项目目录结构

image.png

项目代码

欢迎Star

https://github.com/vouv/chat-room

相关文章

网友评论

      本文标题:[实战]基于Go实现Web聊天室(3种方式)

      本文链接:https://www.haomeiwen.com/subject/uznapxtx.html