golang长连接

qianlnk · · 4177 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

设计思路:每个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

 


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:qianlnk

查看原文:golang长连接

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4177 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传