码迷,mamicode.com
首页 > 其他好文 > 详细

golang长连接

时间:2016-08-05 19:50:21      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

设计思路:每个websocket允许的连接都是有时间限制的,超时后服务端会自动断开连接,那么长连接就在服务端发出断开连接信息后客户端检测断开信息再次发起连接请求,中间再通过握手信息确保客户端同服务器处于连接状态。

设计结构:

 

[plain] view plain copy
 
 技术分享技术分享
  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
 
 技术分享技术分享
  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
 
 技术分享技术分享
  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

 

golang长连接

标签:

原文地址:http://www.cnblogs.com/qianlnk/p/5742526.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!