golang长连接
qianlnk · · 4564 次点击 · · 开始浏览设计思路:每个websocket允许的连接都是有时间限制的,超时后服务端会自动断开连接,那么长连接就在服务端发出断开连接信息后客户端检测断开信息再次发起连接请求,中间再通过握手信息确保客户端同服务器处于连接状态。
设计结构:
- 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
- }
长连接通过`writeCh`通道主动向连接方发送消息,通过`ReadCh`通道读取连接中的信息,设置`ShakeHand`来确定是否要发送握手信息,Status用以标识连接状态。
通过WriteLoop来发送握手信息,同时监听`WriteCh`通道,转发通道里的消息。
- //call func with a gorouting, it will send shake hands message to service to make sure self is ok
- //if you want to send message call func 'Write', and the case writeCh will 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()
- }
通过ReadLoop来接受信息,同时将消息转发到`ReadCh`通道内。
- //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()
- }
然后可以通过Read函数将消息转发到形如
type dealmsg func([]byte, *Longsocket) error
的函数中去做相应的消息处理,当然你也可以通过Longsocket参数发送相应的处理消息。
源码已上传githup如下,其中有demo供参考。
https://github.com/qianlnk/longsocket
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
设计思路:每个websocket允许的连接都是有时间限制的,超时后服务端会自动断开连接,那么长连接就在服务端发出断开连接信息后客户端检测断开信息再次发起连接请求,中间再通过握手信息确保客户端同服务器处于连接状态。
设计结构:
- 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
- }
长连接通过`writeCh`通道主动向连接方发送消息,通过`ReadCh`通道读取连接中的信息,设置`ShakeHand`来确定是否要发送握手信息,Status用以标识连接状态。
通过WriteLoop来发送握手信息,同时监听`WriteCh`通道,转发通道里的消息。
- //call func with a gorouting, it will send shake hands message to service to make sure self is ok
- //if you want to send message call func 'Write', and the case writeCh will 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()
- }
通过ReadLoop来接受信息,同时将消息转发到`ReadCh`通道内。
- //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()
- }
然后可以通过Read函数将消息转发到形如
type dealmsg func([]byte, *Longsocket) error
的函数中去做相应的消息处理,当然你也可以通过Longsocket参数发送相应的处理消息。
源码已上传githup如下,其中有demo供参考。