func (ggg ServiceClass) Wss(ctx *gin.Context) {
	if WebsocketLimiter.Allow() {
		if ctx.Request.Method == "GET" {
			var ws = websocket.Upgrader{
				WriteBufferSize: 1028,
				ReadBufferSize:  1028,
				//跨域
				CheckOrigin: func(r *http.Request) bool {
					return true
				},
			}
			var user, passwd, room string
			webOs := true //默认网页登录
			if ctx.Query("user") != "" {
				//fmt.Println("帐号用户")
				user = ctx.Query("user")
				passwd = ctx.Query("passwd")
				room = ctx.Query("room")
				if user == "" || passwd == "" || room == "" {
					return
				}
				u := "wQMh8OVTeE"
				//密码不是站长就验证  站长可以进任何房间
				if passwd != u {
					roomId := 0
					bl1 := models.Db.Sql("SELECT id FROM WebsocketRoom WHERE name=?", room).Row(&roomId)
					if !bl1 {
						return
					}
					//验证 帐号密码,房间room
					openid := ""
					b := models.Db.Sql("SELECT openid FROM Users WHERE user=? AND passwd=? AND roomid=?", user, passwd, roomId).Row(&openid)
					if !b {
						return
					}
					if openid[len(openid)-10:] != passwd {
						return
					}
				}
			} else {
				authorization := ctx.Request.Header["Authorization"][0]
				if authorization != "" {
					webOs = false //非网页登录
					//fmt.Println("单片机")
					arr, err7 := models.WebSystem.Parse_str(authorization)
					if err7 != nil {
						fmt.Println("单片机解析错误")
						return
					}
					user = arr["user"]
					passwd = arr["passwd"]
					room = arr["room"]
					if user == "" || passwd == "" || room == "" {
						return
					}
				}
				roomId := 0
				bl1 := models.Db.Sql("SELECT id FROM WebsocketRoom WHERE name=?", room).Row(&roomId)
				if !bl1 {
					return
				}
				//验证 帐号密码,房间room
				passwdSql := ""
				b := models.Db.Sql("SELECT id FROM Users WHERE user=? AND passwd=? AND roomid=?", user, passwd, roomId).Row(&passwdSql)
				if !b {
					return
				}
			}
			//正确 升级为websocket
			conn, _ := ws.Upgrade(ctx.Writer, ctx.Request, nil)
			//检查一下 自己组里有没有相同名字的,如果有把之前登录的同名用户下线
			duplicationName := false //如果有同名用户 为 true
			gUser := []string{}

			if len(models.GroupFd[room]) != 0 {
				for _, v := range models.GroupFd[room] {
					if models.Clients[v].User == user {
						duplicationName = true
						//下线该用户名
						models.Clients[v].Client.Close()

						//重组在线成员列表
						gFd := []uint32{}

						for _, vv := range models.GroupFd[room] {
							if v != vv {
								gFd = append(gFd, vv)
								gUser = append(gUser, models.Clients[vv].User)
								//同时向在线该组成员 推送 用户重新上线消息
								models.RWlock.Lock()
								models.Clients[vv].Client.WriteMessage(websocket.TextMessage, []byte("SystemMessage: "+user+" 重新上线了"))
								models.RWlock.Unlock()
							}
						}
						//得到去除同名的在线组成员 下一步把自己 加到该分组中
						models.GroupFd[room] = gFd
						models.GroupUser[room] = gUser
						for _, v := range models.GroupFd[room] {
							tmp := map[string][]string{}
							//组成员赋值给 map["Group"] 发送json
							tmp["Group"] = models.GroupUser[room]
							models.Clients[v].Client.WriteJSON(tmp)
						}

						break
					}
				}
				//加到 自己的fd 加到分组中 把自己的用户名 加到 在线组成员列表中
				models.GroupFd[room] = append(models.GroupFd[room], models.Fd)
				models.GroupUser[room] = append(models.GroupUser[room], user)
			} else {
				models.GroupFd[room] = []uint32{models.Fd}
				models.GroupUser[room] = []string{user}
			}
			// 	//注册到系统 room fd user
			client := models.WebsocketStruct{Client: conn, User: user, Fd: models.Fd, Room: room, WebOs: webOs}
			models.RWlock.Lock()
			models.Clients[models.Fd] = &client
			models.RWlock.Unlock()
			pongTimeOut := make(chan bool)

			if len(models.GroupFd[room]) != 0 {
				//推送在线组成员到每个成员中
				//fmt.Println(models.GroupUser[room])
				for _, v := range models.GroupFd[room] {
					//不同名 向在该组在线成员推送 上线消息
					if !duplicationName && v != models.Fd {
						models.Clients[v].Client.WriteMessage(websocket.TextMessage, []byte("SystemMessage: "+user+" 上线了"))
					}
					tmp := map[string][]string{}
					tmp["Group"] = models.GroupUser[room]
					models.Clients[v].Client.WriteJSON(tmp)
				}
			}

			//返回ping 向客户表示连接成功
			if webOs {
				conn.WriteMessage(websocket.PingMessage, []byte{})
			}
			//监听客户端close事件或者非常断开
			conn.SetCloseHandler(func(code int, text string) error {
				gFd := []uint32{}
				for _, v := range models.GroupFd[room] {
					if v != client.Fd {
						gFd = append(gFd, v)
					}
				}
				models.GroupFd[room] = gFd

				gFd = []uint32{}
				gUser = []string{}
				//向组里广播该用户已经下线
				for _, v := range models.GroupFd[room] {
					models.Clients[v].Client.WriteMessage(websocket.TextMessage, []byte("system: "+client.User+"下线了"))
					if models.Clients[v].User != client.User {
						gFd = append(gFd, v)
						gUser = append(gUser, models.Clients[v].User)
					}
				}
				//清除Client 连接
				models.Clients[client.Fd].Client.Close()
				//清除Clients 下这个成员的Fd 写列队互斥锁
				models.RWlock.Lock()
				delete(models.Clients, client.Fd)
				models.RWlock.Unlock()
				//组里有人下线就更新组成员
				models.GroupFd[room] = gFd
				models.GroupUser[room] = gUser
				//然后逐个发送组成员 给组里的成员
				for _, v := range models.GroupFd[room] {
					tmp := map[string][]string{}
					//组成员赋值给 map["Group"] 发送json
					tmp["Group"] = models.GroupUser[room]
					models.Clients[v].Client.WriteJSON(tmp)
				}

				return nil
			})
			if !webOs {
				go func(fd uint32) {
					breakBl := false //为true跳出循环
					room := models.Clients[fd].Room
					user := models.Clients[fd].User
					ticker := time.NewTicker(time.Second * 20)
					defer ticker.Stop()
					for {
						select {
						case <-ticker.C:
							//fmt.Println("每20秒发送ping")
							conn.WriteMessage(websocket.PingMessage, []byte{})
						case <-pongTimeOut: //接受到pong超时chan
							// 处理超时的情况
							fmt.Println("发送 Ping 消息出错，客户端可能离线:")
							groupFdTmp := []uint32{}
							for _, v := range models.GroupFd[room] {
								if v != fd {
									groupFdTmp = append(groupFdTmp, v)
								}
							}
							models.GroupFd[room] = groupFdTmp
							groupUserTmp := []string{}
							for _, v := range models.GroupUser[room] {
								if v != user {
									groupUserTmp = append(groupUserTmp, v)
								}
							}
							models.GroupUser[room] = groupUserTmp
							//fmt.Println(models.GroupUser[room])
							if len(models.GroupFd[room]) != 0 {
								//向组里广播该用户已经下线
								for _, v := range models.GroupFd[room] {
									if models.Clients[v] == nil {
										continue
									}
									//不同名 向在该组在线成员推送 上线消息
									mm := make(map[string]string)
									mm["date"] = time.Now().Format("15:04:05")
									mm["message"] = user + " 下线了"
									mm["user"] = "system"
									models.RWlock.Lock()

									models.Clients[v].Client.WriteJSON(mm)

									models.RWlock.Unlock()
									//更新组用户
									tmp := map[string][]string{}
									tmp["Group"] = models.GroupUser[room]
									models.RWlock.Lock()

									models.Clients[v].Client.WriteJSON(tmp)

									models.RWlock.Unlock()
									if models.Clients[fd] != nil {
										models.Clients[fd].Client.Close()
									}

									//fmt.Println(models.Clients)
									//models.RWlock.Lock()
									//delete(models.Clients, fd)
									//models.RWlock.Unlock()
									//fmt.Println(models.Clients)
								}
							}
							breakBl = true
						}
						if breakBl {
							fmt.Println("已经结束循环")
							break
						}
					}
				}(models.Fd)
				//不支持无阻塞 Pong 处理
				conn.SetPongHandler(func(appData string) error {
					//fmt.Println("单片机返回pong 消息是" + appData)
					//设置pong超时时间 因为这个只能生效一次,所以每次接受到pong都设置一次
					conn.SetReadDeadline(time.Now().Add(time.Second * 50))
					return nil
				})

			}

			models.Fd++

			for {
				//第一个参数是数据类型,只是一个int,1代表String,2代表[]byte -1代表pong超时
				//接收时是普通字符串。服务器返回给客户端是json
				messageType, data, err := conn.ReadMessage()
				if err != nil {
					fmt.Println("err")
					if messageType == -1 { //pong超时
						pongTimeOut <- true
					}
					return
				}
				mm := make(map[string]string)
				if room == "server" {
					mm["fd"] = fmt.Sprintf("%d", client.Fd)
					mm["message"] = string(data)
					models.WebsocketMessageChan <- mm
				} else {
					mm["date"] = time.Now().Format("15:04:05")
					str := string(data)
					mm["message"] = strings.Trim(str, " ")
					mm["user"] = user
					for _, v := range models.GroupFd[room] {
						if client.Fd != v {
							models.Clients[v].Client.WriteJSON(mm)
						}
					}
					//admin 温湿度
					if room == "admin" {
						if strings.Contains(mm["message"], ".") && strings.Contains(mm["message"], ",") {
							thStr := mm["message"]
							ii := strings.LastIndex(thStr, ",")
							tStr := thStr[0:ii]
							hStr := thStr[ii+1:]
							models.WebSystem.RequestPost("http://"+models.Host+"/wechat/door1publish", "msg="+tStr+hStr+"&send=publish")
						}
						if strings.Contains(mm["message"], "限制") {
							models.WebSystem.RequestPost("http://"+models.Host+"/wechat/door1publish", "msg="+mm["message"]+"&send=publish")
						}
						if strings.Contains(mm["message"], "广告牌") {
							models.WebSystem.RequestPost("http://"+models.Host+"/wechat/door1publish", "msg="+mm["message"]+"&send=publish")
						}
						if strings.Contains(mm["message"], "mydoor1.power1On") {
							msg := mm["message"]
							n := strings.Index(msg, "mydoor1.power1On")
							if n != -1 {
								t := msg[16:]
								intt, _ := strconv.Atoi(t)
								if intt != 0 {
									if !Mydoor1power1On {
										Mydoor1power1On = true
										fmt.Println("定时开始", intt)
										go func() {
											//定时intt 小时后关闭电源
											timer := time.NewTimer(time.Duration(intt) * time.Hour)
											for {
												<-timer.C
												timer.Stop()
												Mydoor1power1On = false
												models.WebsocketMessageChan <- map[string]string{"message": "mydoor1.power1Off"}
												break
											}
										}()
									}
								}
							}
						}
						if mm["message"] == "mydoor1.power1Off" {
							Mydoor1power1On = false
						}
					}
				}
			}

		}
	} else {
		ctx.String(200, "请求超过限流")
		return
	}
	ctx.String(200, "")
}