golang長連接


設計思路:每個websocket允許的連接都是有時間限制的,超時后服務端會自動斷開連接,那么長連接就在服務端發出斷開連接信息后客戶端檢測斷開信息再次發起連接請求,中間再通過握手信息確保客戶端同服務器處於連接狀態。

設計結構:

 

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. type Longsocket struct {  
  2.     Ws         *websocket.Conn  
  3.     writeCh    chan []byte  
  4.     readCh     chan []byte  
  5.     ShakeHand  bool  
  6.     Url        string  
  7.     Protocol   string  
  8.     Origin     string  
  9.     BufferSize int  
  10.     Status     int  
  11.     mu         sync.Mutex  
  12. }  


長連接通過`writeCh`通道主動向連接方發送消息,通過`ReadCh`通道讀取連接中的信息,設置`ShakeHand`來確定是否要發送握手信息,Status用以標識連接狀態。

 

 

通過WriteLoop來發送握手信息,同時監聽`WriteCh`通道,轉發通道里的消息。

 

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. //call func with a gorouting, it will send shake hands message to service to make sure self is ok  
  2. //if you want to send message call func 'Write', and the case writeCh will be vaild  
  3. func (l *Longsocket) WriteLoop() {  
  4.     defer func() {  
  5.         if err := recover(); err != nil {  
  6.             //fmt.Println("writeloop", err)  
  7.         }  
  8.     }()  
  9.   
  10.     for {  
  11.         errCount := 0  
  12.         if l.Status != STATUS_CONNECT {  
  13.             break  
  14.         }  
  15.         select {  
  16.         case <-time.After(time.Second * time.Duration(SHAKE_HANDS_FREQUENCY)):  
  17.             if l.ShakeHand {  
  18.                 _, err := l.Ws.Write([]byte(SHAKE_HANDS_MSG))  
  19.                 if err != nil {  
  20.                     errCount++  
  21.                 }  
  22.             }  
  23.         case msg := <-l.writeCh:  
  24.             _, err := l.Ws.Write(msg)  
  25.             if err != nil {  
  26.                 errCount++  
  27.             }  
  28.         }  
  29.   
  30.         if errCount != 0 {  
  31.             break  
  32.         }  
  33.     }  
  34.     l.Close()  
  35. }  


通過ReadLoop來接受信息,同時將消息轉發到`ReadCh`通道內。

 

 

[plain]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. //read message form socket and write them to readCh  
  2. func (l *Longsocket) ReadLoop() {  
  3.     defer func() {  
  4.         if err := recover(); err != nil {  
  5.             //fmt.Println("readloop", err)  
  6.         }  
  7.     }()  
  8.   
  9.     for {  
  10.         if l.Status != STATUS_CONNECT {  
  11.             break  
  12.         }  
  13.         buf := make([]byte, l.BufferSize)  
  14.         n, err := l.Ws.Read(buf)  
  15.         if err != nil {  
  16.             break  
  17.         }  
  18.   
  19.         if n > 0 {  
  20.             l.readCh <- buf[0:n]  
  21.         }  
  22.     }  
  23.     l.Close()  
  24. }  


然后可以通過Read函數將消息轉發到形如

 

type dealmsg func([]byte, *Longsocket) error

 

的函數中去做相應的消息處理,當然你也可以通過Longsocket參數發送相應的處理消息。

 

源碼已上傳githup如下,其中有demo供參考。

https://github.com/qianlnk/longsocket

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM