main.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/gin-gonic/gin"
  6. "github.com/gorilla/websocket"
  7. "github.com/unrolled/secure"
  8. "net/http"
  9. "os"
  10. "strings"
  11. "sync"
  12. "time"
  13. )
  14. var (
  15. // BasicPort The original port without SSL certificate
  16. BasicPort = `:12080`
  17. // SSLPort "Secure" port with SSL certificate
  18. SSLPort = `:12443`
  19. // websocket.Upgrader specifies parameters for upgrading an HTTP connection to a
  20. // WebSocket connection.
  21. upGrader = websocket.Upgrader{
  22. CheckOrigin: func(r *http.Request) bool { return true },
  23. }
  24. hlSyncMap sync.Map
  25. gm = &sync.Mutex{}
  26. // 默认超时时间,没有得到数据的超时时间 单位:秒
  27. defaultTimeout = 30
  28. isPrint = false
  29. )
  30. type Clients struct {
  31. clientGroup string
  32. clientName string
  33. actionData map[string]chan string
  34. clientWs *websocket.Conn
  35. }
  36. type Message struct {
  37. Action string `json:"action"`
  38. Param string `json:"param"`
  39. }
  40. type logWriter struct{}
  41. func (w logWriter) Write(p []byte) (n int, err error) {
  42. return len(p), nil
  43. }
  44. // is print?
  45. func logPrint(p ...interface{}) {
  46. if isPrint {
  47. fmt.Println(p)
  48. }
  49. }
  50. // NewClient initializes a new Clients instance
  51. func NewClient(group string, name string, ws *websocket.Conn) *Clients {
  52. return &Clients{
  53. clientGroup: group,
  54. clientName: name,
  55. actionData: make(map[string]chan string, 1), // action有消息后就保存到chan里
  56. clientWs: ws,
  57. }
  58. }
  59. // ws, provides inject function for a job
  60. func ws(c *gin.Context) {
  61. group, name := c.Query("group"), c.Query("name")
  62. if group == "" || name == "" {
  63. return
  64. }
  65. wsClient, err := upGrader.Upgrade(c.Writer, c.Request, nil)
  66. if err != nil {
  67. fmt.Println("websocket err:", err)
  68. return
  69. }
  70. client := NewClient(group, name, wsClient)
  71. hlSyncMap.Store(group+"->"+name, client)
  72. for {
  73. //等待数据
  74. _, message, err := wsClient.ReadMessage()
  75. if err != nil {
  76. break
  77. }
  78. msg := string(message)
  79. check := []uint8{104, 108, 94, 95, 94}
  80. strIndex := strings.Index(msg, string(check))
  81. if strIndex >= 1 {
  82. action := msg[:strIndex]
  83. client.actionData[action] <- msg[strIndex+5:]
  84. logPrint("get_message:", msg[strIndex+5:])
  85. //hlSyncMap.Store(group+"->"+name, client)
  86. } else {
  87. fmt.Println(msg, "message error")
  88. }
  89. }
  90. defer func(ws *websocket.Conn) {
  91. _ = ws.Close()
  92. logPrint(group+"->"+name, "下线了")
  93. hlSyncMap.Range(func(key, value interface{}) bool {
  94. //client, _ := value.(*Clients)
  95. if key == group+"->"+name {
  96. hlSyncMap.Delete(key)
  97. }
  98. return true
  99. })
  100. }(wsClient)
  101. }
  102. func wsTest(c *gin.Context) {
  103. testClient, _ := upGrader.Upgrade(c.Writer, c.Request, nil)
  104. for {
  105. //等待数据
  106. _, message, err := testClient.ReadMessage()
  107. if err != nil {
  108. break
  109. }
  110. msg := string(message)
  111. logPrint("接收到测试消息", msg)
  112. _ = testClient.WriteMessage(1, []byte(msg))
  113. }
  114. defer func(ws *websocket.Conn) {
  115. _ = ws.Close()
  116. }(testClient)
  117. }
  118. func GQueryFunc(client *Clients, funcName string, param string, resChan chan<- string) {
  119. WriteDate := Message{}
  120. WriteDate.Action = funcName
  121. if param == "" {
  122. WriteDate.Param = ""
  123. } else {
  124. WriteDate.Param = param
  125. }
  126. data, _ := json.Marshal(WriteDate)
  127. clientWs := client.clientWs
  128. if client.actionData[funcName] == nil {
  129. client.actionData[funcName] = make(chan string, 1) //此次action初始化1个消息
  130. }
  131. gm.Lock()
  132. err := clientWs.WriteMessage(2, data)
  133. gm.Unlock()
  134. if err != nil {
  135. fmt.Println(err, "写入数据失败")
  136. }
  137. resultFlag := false
  138. for i := 0; i < defaultTimeout*10; i++ {
  139. if len(client.actionData[funcName]) > 0 {
  140. res := <-client.actionData[funcName]
  141. resChan <- res
  142. resultFlag = true
  143. break
  144. }
  145. time.Sleep(time.Millisecond * 100)
  146. }
  147. // 循环完了还是没有数据,那就超时退出
  148. if true != resultFlag {
  149. resChan <- "黑脸怪:timeout"
  150. }
  151. defer func() {
  152. close(resChan)
  153. }()
  154. }
  155. func ResultSet(c *gin.Context) {
  156. var getGroup, getName, Action, Param string
  157. //获取参数
  158. getGroup, getName, Action, Param = c.Query("group"), c.Query("name"), c.Query("action"), c.Query("param")
  159. //如果获取不到 说明是post提交的
  160. if getGroup == "" && getName == "" {
  161. //切换post获取方式
  162. getGroup, getName, Action, Param = c.PostForm("group"), c.PostForm("name"), c.PostForm("action"), c.PostForm("param")
  163. }
  164. if getGroup == "" || getName == "" {
  165. c.JSON(400, gin.H{"status": 400, "data": "input group and name"})
  166. return
  167. }
  168. clientName, ok := hlSyncMap.Load(getGroup + "->" + getName)
  169. if ok == false {
  170. c.JSON(400, gin.H{"status": 400, "data": "注入了ws?没有找到当前组和名字"})
  171. return
  172. }
  173. if Action == "" {
  174. c.JSON(200, gin.H{"group": getGroup, "name": getName})
  175. return
  176. }
  177. //取一个ws客户端
  178. client, ko := clientName.(*Clients)
  179. if !ko {
  180. return
  181. }
  182. c2 := make(chan string, 1)
  183. go GQueryFunc(client, Action, Param, c2)
  184. //把管道传过去,获得值就返回了
  185. c.JSON(200, gin.H{"status": 200, "group": client.clientGroup, "name": client.clientName, "data": <-c2})
  186. }
  187. func checkTimeout(c2 chan string) {
  188. // 100ms检查一次
  189. for i := 0; i < defaultTimeout*10; i++ {
  190. if len(c2) > 0 {
  191. return
  192. }
  193. time.Sleep(time.Millisecond * 100)
  194. }
  195. // 循环完了还是没有数据,那就超时退出
  196. c2 <- "黑脸怪:timeout"
  197. }
  198. func Execjs(c *gin.Context) {
  199. var getGroup, getName, JsCode string
  200. Action := "_execjs"
  201. //获取参数
  202. getGroup, getName, JsCode = c.Query("group"), c.Query("name"), c.Query("jscode")
  203. //如果获取不到 说明是post提交的
  204. if getGroup == "" && getName == "" {
  205. //切换post获取方式
  206. getGroup, getName, JsCode = c.PostForm("group"), c.PostForm("name"), c.PostForm("jscode")
  207. }
  208. if getGroup == "" || getName == "" {
  209. c.JSON(400, gin.H{"status": 400, "data": "input group and name"})
  210. return
  211. }
  212. logPrint(getGroup, getName, JsCode)
  213. clientName, ok := hlSyncMap.Load(getGroup + "->" + getName)
  214. if ok == false {
  215. c.JSON(400, gin.H{"status": 400, "data": "注入了ws?没有找到当前组和名字"})
  216. return
  217. }
  218. //取一个ws客户端
  219. client, ko := clientName.(*Clients)
  220. if !ko {
  221. return
  222. }
  223. c2 := make(chan string)
  224. go GQueryFunc(client, Action, JsCode, c2)
  225. c.JSON(200, gin.H{"status": "200", "group": client.clientGroup, "name": client.clientName, "data": <-c2})
  226. }
  227. func getList(c *gin.Context) {
  228. resList := "黑脸怪:\r\n\t"
  229. hlSyncMap.Range(func(key, value interface{}) bool {
  230. resList += key.(string) + "\r\n\t"
  231. return true
  232. })
  233. c.String(200, resList)
  234. }
  235. func Index(c *gin.Context) {
  236. c.String(200, "你好,我是黑脸怪~")
  237. }
  238. func TlsHandler() gin.HandlerFunc {
  239. return func(c *gin.Context) {
  240. secureMiddleware := secure.New(secure.Options{
  241. SSLRedirect: true,
  242. SSLHost: SSLPort,
  243. })
  244. err := secureMiddleware.Process(c.Writer, c.Request)
  245. if err != nil {
  246. c.Abort()
  247. return
  248. }
  249. c.Next()
  250. }
  251. }
  252. func main() {
  253. for _, v := range os.Args {
  254. if v == "log" {
  255. isPrint = true
  256. }
  257. }
  258. // 将默认的日志输出器设置为空
  259. //gin.DefaultWriter = logWriter{}
  260. gin.SetMode(gin.ReleaseMode)
  261. r := gin.Default()
  262. r.GET("/", Index)
  263. r.GET("/go", ResultSet)
  264. r.POST("/go", ResultSet)
  265. r.GET("/ws", ws)
  266. r.GET("/wst", wsTest)
  267. r.GET("/execjs", Execjs)
  268. r.POST("/execjs", Execjs)
  269. r.GET("/list", getList)
  270. r.Use(TlsHandler())
  271. _ = r.Run(BasicPort)
  272. //编译https版放开下面这行注释代码 并且把上一行注释
  273. //_ = r.RunTLS(SSLPort, "zhengshu.pem", "zhengshu.key")
  274. }