This is a creation in Article, where the information may have evolved or changed.
Design ideas: Each websocket allows the connection is time-limited, after timeout, the server will automatically disconnect, then the long connection on the service side after the disconnection information sent by the client to detect the disconnection information to initiate a connection request, and then through the handshake information to ensure that the client is connected with the servers.
Design structure:
[Plain]View Plain Copy
- Type Longsocket struct {
- Ws *websocket. Conn
- Writech Chan []byte
- READCH Chan []byte
- shakehand BOOL
- URL string
- Protocol string
- Origin string
- buffersize int
- Status int
- Mu sync. Mutex
- }
The long connection actively sends a message to the connecting party via the ' Writech ' channel, reading the information in the connection through the ' READCH ' channel, setting ' Shakehand ' to determine whether to send the handshake information, status to identify the connection status.
Through the Writeloop to send handshake information, while listening to the ' Writech ' channel, forward the message in the channel.
[Plain]View Plain Copy
- Call Func with a gorouting, it'll send shake hands message to service to make sure
- If you want to send message call func ' Write ', and the case Writech'll be vaild
- Func (L *longsocket) Writeloop () {
- Defer func () {
- If err: = Recover (); Err! = Nil {
- Fmt. Println ("Writeloop", err)
- }
- }()
- for {
- ErrCount: = 0
- If l.status! = status_connect {
- Break
- }
- Select {
- Case <-time. After (time. Second * time. Duration (shake_hands_frequency)):
- If L.shakehand {
- _, Err: = L.ws.write ([]byte (SHAKE_HANDS_MSG))
- If err! = Nil {
- errcount++
- }
- }
- Case msg: = <-l.writech:
- _, Err: = L.ws.write (msg)
- If err! = Nil {
- errcount++
- }
- }
- If ErrCount! = 0 {
- Break
- }
- }
- L.close ()
- }
The message is received via Readloop and forwarded to the ' READCH ' channel.
[Plain]View Plain Copy
- Read Message form socket and write them to READCH
- Func (L *longsocket) Readloop () {
- Defer func () {
- If err: = Recover (); Err! = Nil {
- Fmt. Println ("Readloop", err)
- }
- }()
- for {
- If l.status! = status_connect {
- Break
- }
- BUF: = Make ([]byte, L.buffersize)
- N, Err: = L.ws.read (BUF)
- If err! = Nil {
- Break
- }
- If n > 0 {
- L.READCH <-Buf[0:n]
- }
- }
- L.close ()
- }
The message can then be forwarded through the Read function to a shape such as
Type dealmsg func ([]byte, *longsocket) error
function to do the corresponding message processing, of course, you can also send the corresponding processing message through the Longsocket parameter.
Source has been uploaded githup as follows, including demo for reference.
Https://github.com/qianlnk/longsocket