This is a creation in Article, where the information may have evolved or changed.
1. Avoid injection (escape)
name := url.QueryEscape(user.Name)
2. Use middleware to process each request, using the session middle tier to process a class of requests.
Intermediate Layer Principle
The middle tier relies on the context to pass variables. The context of a request is not only tied to requests and response, but also handlers Handlerschain. So each request from the client is middleware processed.
The principle is simple: the middleware will handle each request. We define a session object in the middle tier. This will save a session object for each requested context. The Session object determines whether the SessionID is the same session object by judging whether it exists. If it is the same session, then you can get the corresponding value from the session.
The implementation mechanism of session
The server generates a sessionId saved to the cookie. Of course, you can also save all the content in the session to a cookie. Discussion of the former, with SessionId, will carry this sessionId cookie each time it is requested. This way the server can judge whether SessionId exists to get the corresponding session.
3. Package WebSocket
type connection struct {ws *websocket.Conn// send chan []byteuser *Userroom *Room}
4. Create Config Package
Package Mainimport ("Net/url" "OS" "reflect") type Redisconfig struct {Host string ' default: ' redis://localhost:6379 ' ' Pas Sword string ' Default: ' ' '}type serverconfig struct {Port string ' default: ' "" ' Secret string ' default: ' Secret ' '}type Co nfig struct {Redis redisconfigserver serverconfig}//Session expiration (from Github.com/boj/redistore) const Sessionexpire = 86400 * 30var config = Confapp () func confapp () config {_redis: = Confredis (OS). Getenv ("Redis_url")) _server: = Confserver (OS. Getenv ("PORT")) return Config{redis: _redis,server: _server,}}func Confredis (Connurl string) redisconfig {_redis: = Redisconfig{}typ: = reflect. TypeOf (_redis) If Connurl = = "" {h, _: = Typ. Fieldbyname ("Host") _redis. Host = H.tag.get ("Default") p, _: = Typ. Fieldbyname ("Password") _redis. Password = P.tag.get ("Default") return _redis}redisurl, err: = URL. Parse (Connurl) if err! = Nil {panic (err)}auth: = "" if redisurl.user! = nil {if password, OK: = RedisURL.User.Password (); OK {auth = Password}}return redisconfig{Host:redisurl.host,password:auth,}} Func confserver (port string) serverconfig {_conf: = Serverconfig{secret: "Learngo",}typ: = reflect. TypeOf (_conf) If Port = = "" {p, _: = Typ. Fieldbyname ("Port") _conf. Port = P.tag.get ("Default") return _conf}_conf. Port = Portreturn _conf}
5. Encapsulate the Close method of the DB to the middle tier
DB initialization encapsulated into the INIT function
func init() {db.Connect()}
Storage of DB into context through the middle tier
// Connect middleware clones the database session for each request and// makes the `db` object available for each handlerfunc Connect(c *gin.Context) {s := db.Session.Clone()defer s.Close()c.Set("db", s.DB(db.Mongo.Database))c.Next()}
6. The action is logged to the log file
type Log struct {PlayerName string `json:"playername"`Action string `json:"action"`TakeCard Card `json:"takecard"`PutCards []Card `json:"putcards"`Option string `json:"option"`}func (a *Action) ToLog(g *Game) {PutCards := make([]Card, 0)TakeCard := g.CardFromReference(a.TakeCard)for _, id := range a.PutCards {PutCards = append(PutCards, g.CardFromReference(id))}g.LastLog = &Log{a.PlayerName, a.Name, TakeCard, PutCards, a.Option}}