connect

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2020 License: MIT Imports: 15 Imported by: 0

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

View Source
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
		}
	}
})
View Source
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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL