在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
安装Revel框架请参看下面这篇文章:《Go语言Revel框架 准备工作》 http://www.cnblogs.com/ghj1976/archive/2013/03/24/2979709.html 运行聊天室例子只需执行下面命令:
$ revel run github.com/robfig/revel/samples/chat 这时候访问 http://localhost:9000/ 就可以让你选择昵称和连接方式进入聊天的界面。 代码解读目录组织结构这个演示程序的目录组织结构: Here are the contents of the app:
解读 chatroom.go一个聊天室开一个协程来单独处理,chatroom() 函数无限循环运行,处理每次聊天的请求。 func init() { go chatroom() }
chatroom() 函数 在三个 channels 之间 select, 并执行相应的请求操作。 type Event struct { Type string // "join", "leave", or "message" 演示Demo只有这三种类型 User 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 chatroom() { archive := list.New() // 最近的几条聊天记录 subscribers := 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. // 订阅者离开后,从用户列表中删除离开者。 }
} }
当一个新的用户加入时,处理下面事情:
case ch := <-subscribe:
var events []Event for e := archive.Front(); e != nil; e = e.Next() { events = append(events, e.Value.(Event)) } subscriber := make(chan Event, 10) subscribers.PushBack(subscriber) ch <- Subscription{events, subscriber}
当用户发布新聊天内容时,发布的event一个一个发送给订阅者的channel,然后event被添加到archive,archive里面的数量大于10,前面的会被移出。
case event := <-publish:
for ch := subscribers.Front(); ch != nil; ch = ch.Next() { ch.Value.(chan Event) <- event } if archive.Len() >= archiveSize { 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) == unsub { subscribers.Remove(ch) break } } } 对聊天室框架代码解读可以看下面这个思维导图:
参考资料: 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 |
请发表评论