From 078327e8d5760022feb281048de582892f8393ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=B0=B9=E5=B2=9A?= <770236076@qq.com> Date: Tue, 13 Oct 2020 12:02:07 +0800 Subject: [PATCH] event --- controllers/event.go | 181 +++++++++++++++++++++++++++++++++++++++++++ routers/router.go | 5 ++ 2 files changed, 186 insertions(+) create mode 100644 controllers/event.go diff --git a/controllers/event.go b/controllers/event.go new file mode 100644 index 000000000..a6cacc026 --- /dev/null +++ b/controllers/event.go @@ -0,0 +1,181 @@ +package controllers + +import ( + "log" + "net/http" + + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + + "git.rosy.net.cn/jx-callback/globals" + + "git.rosy.net.cn/jx-callback/business/model/dao" + + "git.rosy.net.cn/jx-callback/business/model" + + "github.com/gorilla/websocket" + + "git.rosy.net.cn/baseapi/utils" + + "github.com/astaxie/beego" +) + +// 操作事件明细相关API +type EventController struct { + beego.Controller +} + +//连接的客户端,吧每个客户端都放进来 +var clients = make(map[string][]*websocket.Conn) + +//广播频道(通道) +var broadcast = make(chan map[string]*model.ImMessageRecord) + +// 配置升级程序(升级为websocket) +var upgrader = websocket.Upgrader{} + +// 定义我们的消息对象 +type Message struct { + Data interface{} `json:"data"` +} + +// @Title 得到微信小程序码 +// @Description 得到微信小程序码 +// @Param token header string true "认证token" +// @Param scene formData string true "最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)" +// @Param page formData string false "必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetWeixinUnlimited [post] +func (c *EventController) GetWeixinUnlimited() { + // c.callGetWeixinUnlimited(func(params *tEventGetWeixinUnlimitedParams) (retVal interface{}, errCode string, err error) { + // // api.WeixinMiniAPI2.CBRetrieveToken() + // result, err := api.WeixinMiniAPI2.GetUnlimited(params.Scene, params.Page) + // if err != nil || result == nil { + // return retVal, "", err + // } + // fileName := "wxcode" + utils.Int64ToStr(time.Now().Unix()) + ".jpg" + // retVal, err = jxutils.UploadExportContent([]byte(result["fakeData"].(string)), fileName) + // // tasks.RefreshWeixinToken() + // return retVal, "", err + // }) +} + +// @Title 测试websocket +// @Description 测试websocket +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /TestWebsocket [get] +func (c *EventController) TestWebsocket() { + // 解决跨域问题(微信小程序) + upgrader.CheckOrigin = func(r *http.Request) bool { + return true + } + //升级将HTTP服务器连接升级到WebSocket协议。 + //responseHeader包含在对客户端升级的响应中 + //请求。使用responseHeader指定Cookie(设置Cookie)和 + //应用程序协商的子目录(Sec WebSocket协议)。 + //如果升级失败,则升级将向客户端答复一个HTTP错误 + ws, err := upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil) + if err != nil { + log.Fatal(err) + } + defer ws.Close() + var ( + vendorOrderID = c.GetString("vendorOrderID") + msgMap = make(map[string]*model.ImMessageRecord) + ) + //将当前客户端放入map中 + clients[vendorOrderID] = append(clients[vendorOrderID], ws) + + db := dao.GetDB() + if globals.IsProductEnv() { + _, _, err = jxcontext.New(nil, c.GetString("token"), c.Ctx.ResponseWriter, c.Ctx.Request) + if err != nil { + msg := &CallResult{ + Code: model.ErrCodeGeneralFailed, + Desc: err.Error(), + } + ws.WriteJSON(&msg) + } + } + + c.EnableRender = false //Beego不启用渲染 + + var s *model.ImMessageRecord + for { + //接收客户端的消息 + err := ws.ReadJSON(&s) + if err != nil { + globals.SugarLogger.Debugf("页面可能断开啦 ws.ReadJSON error: %v", err.Error()) + index := 0 + for k, v := range clients[vendorOrderID] { + if v == ws { + index = k + } + } + wsList := clients[vendorOrderID] + clients[vendorOrderID] = clients[vendorOrderID][0:0] + clients[vendorOrderID] = append(clients[vendorOrderID], wsList[0:index]...) + clients[vendorOrderID] = append(clients[vendorOrderID], wsList[index+1:len(wsList)]...) + // delete(clients, ws) //删除map中的客户端 + break //结束循环 + } else { + //接受消息 业务逻辑 + msgMap[vendorOrderID] = s + broadcast <- msgMap + dao.WrapAddIDCULDEntity(s, "") + dao.CreateEntity(db, s) + // fmt.Println("接受到从页面上反馈回来的信息 ", utils.Format4Output(s, false)) + } + } +} + +func init() { + go handleMessages() +} + +//广播推送消息 +func handleMessages() { + for { + //读取通道中的消息 + msg := <-broadcast + globals.SugarLogger.Debugf("clients len %v", len(clients)) + //循环map客户端 + for vendorOrderID, mmsg := range msg { + for _, client := range clients[vendorOrderID] { + //把通道中的消息发送给客户端 + globals.SugarLogger.Debugf("msg %v", utils.Format4Output(mmsg, false)) + err := client.WriteJSON(mmsg) + if err != nil { + globals.SugarLogger.Debugf("client.WriteJSON error: %v", err) + client.Close() //关闭 + index := 0 + for k, v := range clients[vendorOrderID] { + if v == client { + index = k + } + } + wsList := clients[vendorOrderID] + clients[vendorOrderID] = clients[vendorOrderID][0:0] + clients[vendorOrderID] = append(clients[vendorOrderID], wsList[0:index]...) + clients[vendorOrderID] = append(clients[vendorOrderID], wsList[index+1:len(wsList)]...) + // delete(clients, client) //删除map中的客户端 + } + } + } + } +} + +// @Title 查询聊天记录 +// @Description 查询聊天记录 +// @Param token header string true "认证token" +// @Param vendorOrderID query string true "订单号" +// @Success 200 {object} controllers.CallResult +// @Failure 200 {object} controllers.CallResult +// @router /GetImMessageRecord [get] +func (c *EventController) GetImMessageRecord() { + // c.callGetImMessageRecord(func(params *tEventGetImMessageRecordParams) (retVal interface{}, errCode string, err error) { + // retVal, err = dao.GetImMessageRecord(dao.GetDB(), params.VendorOrderID, "", 0, -1) + // return retVal, "", err + // }) +} diff --git a/routers/router.go b/routers/router.go index 4feef4941..4201623ed 100644 --- a/routers/router.go +++ b/routers/router.go @@ -46,6 +46,11 @@ func init() { &controllers.JobController{}, ), ), + beego.NSNamespace("/event", + beego.NSInclude( + &controllers.EventController{}, + ), + ), ) beego.AddNamespace(ns) beego.AutoRouter(&controllers.TongLianController{})