Go语言Revel框架 的聊天室示例解读

阅读 46

2023-07-18

安装Revel框架请参看下面这篇文章:《Go语言Revel框架 准备工作》 

运行聊天室例子

运行聊天室例子只需执行下面命令:

$ revel run github.com/robfig/revel/samples/chat

$ revel run github.com/robfig/revel/samples/chat
~
~ revel! http://robfig.github.com/revel
~
2013/03/25 11:54:42 revel.go:240: Loaded module static
2013/03/25 11:54:42 run.go:57: Running chat (github.com/robfig/revel/samples/chat) in dev mode
2013/03/25 11:54:42 harness.go:143: Listening on :9000
2013/03/25 11:54:55 revel.go:240: Loaded module static
2013/03/25 11:54:55 main.go:26: Running revel server
2013/03/25 11:54:55 i18n.go:93: Error reading messages files: lstat /Users/cybercare/go/src/github.com/robfig/revel/samples/chat/messages: no such file or directory
Listening on port 52482...

这时候访问 http://localhost:9000/ 就可以让你选择昵称和连接方式进入聊天的界面。

Go语言Revel框架 的聊天室示例解读_github

代码解读

目录组织结构

这个演示程序的目录组织结构:

Here are the contents of the app:

chat/app/
 chatroom # Chat room routines 聊天室协程
 chatroom.go 
 controllers 
 app.go # The welcome screen, allowing user to pick a technology 欢迎页面,允许客户选择一个数据
 refresh.go # Handlers for the "Active Refresh" chat demo 定时刷新的聊天室Demo
 longpolling.go # Handlers for the "Long polling" ("Comet") chat demo 长连接 Comet技术的聊天室
 websocket.go # Handlers for the "Websocket" chat demo Websocket 技术的聊天室
 views 
 ... # HTML and Javascript


解读 chatroom.go 

一个聊天室开一个协程来单独处理,chatroom() 函数无限循环运行,处理每次聊天的请求。

func
     go
}
 
chatroom() 函数 在三个 channels 之间 select, 并执行相应的请求操作。
type Event struct {
    Type      string // "join", "leave", or "message" 演示Demo只有这三种类型
string // 发出事件的用户名
    Timestamp int    // Unix timestmap (secs) 发出事件的系统时间
    Text      string // What the user said (if Type == "message")  用户说的内容,只有 Type=message时,才会有这个信息。
}
 
type Subscription struct
    Archive []Event      // All the events from the archive.  归档的所有事件
    New     <-chan Event // New events coming in.  新到来的事件
}

var (
    // Send a channel here to get room events back.  It will send the entire
    // archive initially, and then new messages as they come in.
    // 当有新用户加入时,初始化的一些订阅信息。
    subscribe = make(chan (chan<- Subscription), 10)

    // Send a channel here to unsubscribe.
    // 在信道channel中发送退订。
    unsubscribe = make(chan (<-chan Event), 10)

    // Send events here to publish them.
    // 在这里发送事件
    publish = make(chan Event, 10)
)
 
// This function loops forever, handling the chat room pubsub
func
:= list.New()      // 最近的几条聊天记录
:= list.New()  // 订阅者列表
 
for
select
case ch := <-subscribe:
            // Add subscriber to list and send back subscriber channel + chat log.
            // 当有新用户加入聊天时,添加到用户列表并给该用户发送 channel 和聊天记录。
case event := <-publish:
            // Send event to all subscribers and add to chat log.
            // 发送 Event 给所有订阅者,并且增加到聊天记录中。
        case unsub :=<-unsubscribe:
            // Remove subscriber from subscriber list.
            // 订阅者离开后,从用户列表中删除离开者。
        }
    }
}

当一个新的用户加入时,处理下面事情:

  1. 把最新的聊天记录Copy出来,以便提供给新来的用户。
  2. 把用户订阅channel加入到聊天者channel清单中。
  3. 聊天订阅者获得新信息的 channel 

case ch := <-subscribe:
 
var
for e := archive.Front(); e != nil; e = e.Next() {
append(events, e.Value.(Event))
            }
:= make(chan Event, 10)
            subscribers.PushBack(subscriber)
<-

 

当用户发布新聊天内容时,发布的event一个一个发送给订阅者的channel,然后event被添加到archive,archive里面的数量大于10,前面的会被移出。

 

case event := <-publish:
 
for ch := subscribers.Front(); ch != nil; ch = ch.Next() {
chan Event) <-
            }
if archive.Len() >=
                archive.Remove(archive.Front())
            }
            archive.PushBack(event)

 

当有用户离开聊天室时,订阅者channel在list中被移除。

case unsub := <-unsubscribe:
 
for ch := subscribers.Front(); ch != nil; ch = ch.Next() {
if ch.Value.(chan Event) ==
                    subscribers.Remove(ch)
break
                }
            }
        }

对聊天室框架代码解读可以看下面这个思维导图:

Go语言Revel框架 的聊天室示例解读_聊天室_02

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

参考资料:

http://robfig.github.com/revel/index.html

http://robfig.github.com/revel/samples/chat.html

http://robfig.github.com/revel/samples/index.html

Revel示例 - 聊天室

 

http://bbs.studygolang.com/thread-291-1-1.html 

精彩评论(0)

0 0 举报