Documentation ¶
Overview ¶
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Copyright 2019-2020 Axetroy. All rights reserved. MIT license.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var UserRouter = router.Handler(func(c router.Context) { upgrader := websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } websocket, err := upgrader.Upgrade(c.Writer(), c.Request(), nil) if err != nil { c.ResponseFunc(nil, func() schema.Response { return schema.Response{ Message: http.StatusText(http.StatusInternalServerError), Status: schema.StatusFail, Data: nil, } }) return } client := ws.NewClient(websocket) ws.UserPoll.Add(client) defer func() { if r := recover(); r != nil { switch t := r.(type) { case string: err = errors.New(t) case error: err = t default: err = exception.Unknown } fmt.Printf("%+v\n", err) } waiterId := ws.MatcherPool.GetMyWaiter(client.UUID) if waiterId != nil { waiterClient := ws.WaiterPoll.Get(*waiterId) _ = waiterClient.WriteJSON(ws.Message{ From: client.UUID, To: *waiterId, Type: string(ws.TypeResponseWaiterDisconnected), Payload: nil, }) hash := util.MD5(client.UUID + waiterClient.UUID) now := time.Now() _ = database.Db.Model(model.CustomerSession{}).Where("id = ?", hash).Update(model.CustomerSession{ ClosedAt: &now, }).Error } ws.UserPoll.Remove(client.UUID) ws.MatcherPool.Leave(client.UUID) ws.MatcherPool.Broadcast <- true _ = client.Close() }() ticker := time.NewTicker(time.Minute * 1) defer func() { ticker.Stop() }() go func() { isIdle := false for range ticker.C { if client.Closed { ticker.Stop() break } now := time.Now() if client.LatestReceiveAt.Add(time.Minute * 10).Before(now) { if isIdle { _ = client.WriteJSON(ws.Message{ Type: string(ws.TypeResponseUserDisconnected), To: client.UUID, Date: time.Now().Format(time.RFC3339Nano), }) ws.MatcherPool.Leave(client.UUID) _ = client.Close() ticker.Stop() break } else { _ = client.WriteJSON(ws.Message{ Type: string(ws.TypeResponseUserIdle), To: client.UUID, Payload: map[string]interface{}{ "message": "当前连接出于空闲状态,如果您未回复,则在 60 秒钟之后断开连接", }, Date: time.Now().Format(time.RFC3339Nano), }) isIdle = true } } else { isIdle = false } } }() for { client.LatestReceiveAt = time.Now() var msg ws.Message err := websocket.ReadJSON(&msg) if err != nil { _ = client.WriteError(exception.InvalidParams.New(err.Error()), msg) continue } if err := validator.ValidateStruct(msg); err != nil { _ = client.WriteError(exception.InvalidParams.New(err.Error()), msg) continue } typeCondition: switch ws.TypeRequestUser(msg.Type) { case ws.TypeRequestUserAuth: if err := userTypeAuthHandler(client, msg); err != nil { _ = client.WriteError(err, msg) } break typeCondition case ws.TypeRequestUserConnect: if err := userTypeConnectHandler(client, msg); err != nil { _ = client.WriteError(err, msg) } break typeCondition case ws.TypeRequestUserGetHistory: if err := userTypeGetHistoryHandler(client); err != nil { _ = client.WriteError(err, msg) } break typeCondition case ws.TypeRequestUserDisconnect: if err := userTypeDisconnectHandler(client); err != nil { _ = client.WriteError(err, msg) } break typeCondition case ws.TypeRequestUserMessageText: if err := userTypeMessageHandler(client, msg); err != nil { _ = client.WriteError(err, msg) } break typeCondition case ws.TypeRequestUserMessageImage: if err := userTypeMessageImageHandler(client, msg); err != nil { _ = client.WriteError(err, msg) } break typeCondition case ws.TypeRequestUserRate: if err := userTypeRateHandler(client, msg); err != nil { _ = client.WriteError(err, msg) } break typeCondition default: _ = client.WriteError(exception.InvalidParams.New("未知的消息类型"), msg) break typeCondition } } })
var WaiterRouter = router.Handler(func(c router.Context) { var ( client *ws.Client ) upgrader := websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } webscoket, err := upgrader.Upgrade(c.Writer(), c.Request(), nil) if err != nil { c.ResponseFunc(nil, func() schema.Response { return schema.Response{ Message: http.StatusText(http.StatusInternalServerError), Status: schema.StatusFail, Data: nil, } }) return } defer func() { if r := recover(); r != nil { switch t := r.(type) { case string: err = errors.New(t) case error: err = t default: err = exception.Unknown } fmt.Printf("%+v\n", err) } _ = webscoket.Close() if client != nil { ws.WaiterPoll.Remove(client.UUID) users := ws.MatcherPool.GetMyUsers(client.UUID) for _, user := range users { userSocket := ws.UserPoll.Get(user) if userSocket != nil { _ = userSocket.WriteJSON(ws.Message{ From: client.UUID, To: user, Type: string(ws.TypeResponseUserDisconnected), Payload: nil, Date: time.Now().Format(time.RFC3339Nano), }) hash := util.MD5(userSocket.UUID + client.UUID) now := time.Now() _ = database.Db.Model(model.CustomerSession{}).Where("id = ?", hash).Update(model.CustomerSession{ ClosedAt: &now, }).Error } } ws.MatcherPool.RemoveWaiter(client.UUID) ws.MatcherPool.Broadcast <- true } }() client = ws.NewClient(webscoket) ws.WaiterPoll.Add(client) for { var msg ws.Message err := webscoket.ReadJSON(&msg) if err != nil { _ = client.WriteError(exception.InvalidParams.New(err.Error()), msg) continue } if err := validator.ValidateStruct(msg); err != nil { _ = client.WriteError(exception.InvalidParams.New(err.Error()), msg) continue } typeCondition: switch ws.TypeRequestWaiter(msg.Type) { case ws.TypeRequestWaiterAuth: if er := waiterTypeAuthHandler(client, msg); er != nil { _ = client.WriteError(er, msg) } break typeCondition case ws.TypeRequestWaiterReady: if er := waiterTypeReadyHandler(client); er != nil { _ = client.WriteError(er, msg) } break typeCondition case ws.TypeRequestWaiterUnReady: if er := waiterTypeUnReadyHandler(client); er != nil { _ = client.WriteError(er, msg) } break typeCondition case ws.TypeRequestWaiterGetHistory: if er := waiterTypeGetHistoryHandler(client, msg); er != nil { _ = client.WriteError(er, msg) } break typeCondition case ws.TypeRequestWaiterGetHistorySession: if er := waiterTypeGetHistorySessionHandler(client, msg); er != nil { _ = client.WriteError(er, msg) } break typeCondition case ws.TypeRequestWaiterDisconnect: if er := waiterTypeDisconnectHandler(client, msg); er != nil { _ = client.WriteError(er, msg) } break typeCondition case ws.TypeRequestWaiterMessageText: if er := waiterTypeMessageHandler(client, msg); er != nil { _ = client.WriteError(exception.InvalidParams.New(er.Error()), msg) } break typeCondition case ws.TypeRequestWaiterMessageImage: if er := waiterTypeMessageImageHandler(client, msg); er != nil { _ = client.WriteError(exception.InvalidParams.New(er.Error()), msg) } break typeCondition case ws.TypeRequestWaiterRate: if er := waiterTypeRateHandler(client, msg); er != nil { _ = client.WriteError(exception.InvalidParams.New(er.Error()), msg) } break typeCondition default: _ = client.WriteError(exception.InvalidParams.New("未知的消息类型"), msg) break typeCondition } } })
Functions ¶
This section is empty.
Types ¶
This section is empty.
Source Files ¶
- user.go
- user_type_auth.go
- user_type_connect.go
- user_type_disconnect.go
- user_type_get_history.go
- user_type_message_image.go
- user_type_message_text.go
- user_type_rate.go
- waiter.go
- waiter_type_auth.go
- waiter_type_disconnect.go
- waiter_type_get_history.go
- waiter_type_message_image.go
- waiter_type_message_text.go
- waiter_type_rate.go
- waiter_type_ready.go
- waiter_type_unready.go