当前位置:   article > 正文

websocket消息服务

makewsmessage

 

目的:搭建websocket服务,用浏览器与服务进行消息交互(写的第一个Go程序)

 

代码目录结构:

 

前端html页面:

  client.html

 

server.go代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package  main
 
import  (
     "fmt"
     "github.com/gorilla/websocket"
     "go_websocket"
     "net/http"
)
 
// http升级websocket协议的配置
var  wsUpgrader = websocket.Upgrader{
     // 允许跨域CORS
     CheckOrigin:  func (r *http.Request) bool {
         return  true
     },
}
 
// 消息处理
func  wsHandler(resp http.ResponseWriter, req *http.Request) {
     wsSocket, err := wsUpgrader.Upgrade(resp, req, nil)
     if  err != nil {
         return
     }
     wsConn := go_websocket.WsConnectionInit(wsSocket)
     wsConn.Run()
 
     for  {
         wsmsg, err := wsConn.ReadMessage()
         if  err != nil {
             goto  error
         }
         err = wsConn.WriteMessage(wsmsg)
         if  err != nil {
             goto  error
         }
     }
error:
     fmt.Println( "websocket is closed" )
     return
}
 
func  main() {
     fmt.Println( "websocket start" )
     http.HandleFunc( "/ws" , wsHandler)
     http.ListenAndServe( "0.0.0.0:7777" , nil)
}

 

connection.go代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package  go_websocket
 
import  (
     "errors"
     "fmt"
     "github.com/gorilla/websocket"
     "sync"
     "time"
)
 
// 客户端读写消息
type  WsMessage  struct  {
     msgType int
     data    []byte
}
 
// 客户端连接
type  wsConnection  struct  {
     wsSocket *websocket.Conn
     inChan    chan  *WsMessage
     outChan   chan  *WsMessage
 
     isClosed  bool
     closeChan  chan  []byte
     mutex     sync.Mutex
}
 
// 连接初始化
func  WsConnectionInit(wsSocket *websocket.Conn) (wsConn *wsConnection) {
     wsConn = &wsConnection{
         wsSocket:  wsSocket,
         inChan:    make( chan  *WsMessage, 1000),
         outChan:   make( chan  *WsMessage, 1000),
         closeChan: make( chan  []byte, 1),
     }
     return  wsConn
}
 
// 启动
func  (wsConn *wsConnection) Run() {
     go  wsConn.readLoop()
     go  wsConn.writeLoop()
     go  wsConn.heartbeat()
}
 
// 心跳检测
func  (wsConn *wsConnection) heartbeat() {
     for  {
         time.Sleep(2 * time.Second)
         wsmsg := &WsMessage{msgType: websocket.TextMessage, data: []byte( "heartbeat" )}
         err := wsConn.WriteMessage(wsmsg)
         if  err != nil {
             fmt.Println( "send heartbeat stop" )
             return
         }
     }
}
 
// 循环接收
func  (wsConn *wsConnection) readLoop() {
     var  ()
 
     for  {
         msgType, data, err := wsConn.wsSocket.ReadMessage()
         if  err != nil {
             goto  error
         }
         select  {
         case  wsConn.inChan <- &WsMessage{msgType: msgType, data: data}:
         case  <-wsConn.closeChan:
             goto  closed
         }
     }
error:
     wsConn.Close()
closed:
     fmt.Println( "readLoop closed" )
}
 
// 循环发送
func  (wsConn *wsConnection) writeLoop() {
     for  {
         select  {
         case  wsmsg := <-wsConn.outChan:
             if  err := wsConn.wsSocket.WriteMessage(wsmsg.msgType, wsmsg.data); err != nil {
                 goto  error
             }
         case  <-wsConn.closeChan:
             goto  closed
         }
     }
error:
     wsConn.Close()
closed:
     fmt.Println( "writeLoop close" )
}
 
// 取消息,外部可调用
func  (wsConn *wsConnection) ReadMessage() (wsmsg *WsMessage, err error) {
     select  {
     case  wsmsg = <-wsConn.inChan:
         return  wsmsg, nil
     case  <-wsConn.closeChan:
         return  nil, errors.New( "websocket is closed" )
     }
}
 
// 写消息,外部可调用
func  (wsConn *wsConnection) WriteMessage(wsmsg *WsMessage) (err error) {
     select  {
     case  wsConn.outChan <- wsmsg:
     case  <-wsConn.closeChan:
         return  errors.New( "websocket is closed" )
     }
     return  nil
}
 
// 关闭wsSocket
func  (wsConn *wsConnection) Close() {
     wsConn.wsSocket.Close()
 
     // 加锁
     wsConn.mutex.Lock()
     if  !wsConn.isClosed {
         wsConn.isClosed = true
         close(wsConn.closeChan)
     }
     wsConn.mutex.Unlock()
}

  

效果展示:

 

转载于:https://www.cnblogs.com/zhangjin007/p/11487092.html

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号