func (this *OnlineUser) PushToClient() {
for b := range this.Send {
err := websocket.JSON.Send(this.Connection, b)
if err != nil {
break
}
}
}
下面我们来看看程序流程,BuildConnection 函数在 main 函数中被注册为 websocket 连接的处理器:
http.Handle("/chat", websocket.Handler(wscon.BuildConnection))
当有一个 websocket 连接请求,该函数将做一些初始化工作用于处理新的连接:
func BuildConnection(ws *websocket.Conn) {
email := ws.Request().URL.Query().Get("email")
onlineUser := &OnlineUser{
InRoom: runningActiveRoom,
Connection: ws,
Send: make(chan Message, 256),
UserInfo: &User{
Email: email,
Name: strings.Split(email, "@")[0],
Gravatar: libs.UrlSize(email, 20),
},
}
runningActiveRoom.OnlineUsers[email] = onlineUser
m := Message{
MType: STATUS_MTYPE,
UserStatus: UserStatus{
Users: runningActiveRoom.GetOnlineUsers(),
},
}
runningActiveRoom.Broadcast <- m
go onlineUser.PushToClient()
onlineUser.PullFromClient()
onlineUser.killUserResource()
}
最后一部分是客户端的实现,这是采用 JavaScript 实现的。它打开了一个新的 websocket 连接到聊天服务器,并注册回调函数用于处理来自服务器端的消息。你会发现当连接收到新的消息时,conn.onmessage 将被调用。现在你只需将接收到的消息交给对应的 JavaScript 函数去处理:
if (window["WebSocket"]) {
conn = new WebSocket("ws://{{.WebSocketHost}}/chat?email={{.Email}}");
conn.onopen = function() {};
conn.onmessage = function(evt) {
var data = JSON.parse(evt.data);
switch(data.MType) {
case "text_mtype":
addMessage(data.TextMessage)
break;
case "status_mtype":
updateUsers(data.UserStatus)
break;
default:
}
};
conn.onerror = function() {
errorMessage("<strong> An error just occured.<strong>")
};
conn.onclose = function() {
errorMessage("<strong>Connection closed.<strong>")
};
} else {
errorMessage("Your browser does not support WebSockets.");
}
如果你对这个应用很感兴趣,你可以从这里获取整个应用的源码:gochatting.