// websocket,统计在线用户数 // uri: /ws func (this *WebsocketController) Ws(wsConn *websocket.Conn) { defer wsConn.Close() this.mutex.Lock() this.ServerId++ serverId := this.ServerId this.mutex.Unlock() req := wsConn.Request() user := goutils.MustInt(req.FormValue("uid")) if user == 0 { user = int(goutils.Ip2long(goutils.RemoteIp(req))) } userData := logic.Book.AddUser(user, serverId) // 给自己发送消息,告诉当前在线用户数、历史最高在线人数 onlineInfo := map[string]int{"online": logic.Book.Len(), "maxonline": logic.MaxOnlineNum()} message := logic.NewMessage(logic.WsMsgOnline, onlineInfo) err := websocket.JSON.Send(wsConn, message) if err != nil { logger.Errorln("Sending onlineusers error:", err) } var clientClosed = false for { select { case message := <-userData.MessageQueue(serverId): if err := websocket.JSON.Send(wsConn, message); err != nil { clientClosed = true } // 心跳 case <-time.After(30e9): if err := websocket.JSON.Send(wsConn, ""); err != nil { clientClosed = true } } if clientClosed { logic.Book.DelUser(user, serverId) logger.Infoln("user:"******"client close") break } } // 用户退出时需要变更其他用户看到的在线用户数 if !logic.Book.UserIsOnline(user) { message := logic.NewMessage(logic.WsMsgOnline, map[string]int{"online": logic.Book.Len()}) go logic.Book.BroadcastAllUsersMessage(message) } }
func executeTpl(ctx echo.Context, tpl *template.Template, data map[string]interface{}) error { objLog := logic.GetLogger(ctx) // 如果没有定义css和js模板,则定义之 if jsTpl := tpl.Lookup("js"); jsTpl == nil { tpl.Parse(`{{define "js"}}{{end}}`) } if jsTpl := tpl.Lookup("css"); jsTpl == nil { tpl.Parse(`{{define "css"}}{{end}}`) } // 当前用户信息 curUser, ok := ctx.Get("user").(*model.Me) if ok { data["me"] = curUser } else { data["me"] = map[string]interface{}{} } // websocket主机 if global.OnlineEnv() { data["wshost"] = config.ConfigFile.MustValue("global", "domain") } else { data["wshost"] = global.App.Host + ":" + global.App.Port } global.App.SetUptime() data["app"] = global.App data["online_users"] = map[string]int{"online": logic.Book.Len(), "maxonline": logic.MaxOnlineNum()} buf := new(bytes.Buffer) err := tpl.Execute(buf, data) if err != nil { objLog.Errorln("excute template error:", err) return err } return ctx.HTML(http.StatusOK, buf.String()) }