内容简介:实现代码如下:首先定义一个结构体wsConn websocket的长链接的实体
实现代码如下:
import (
"errors"
"github.com/gorilla/websocket"
"sync"
)
type Connection struct {
wsConn *websocket.Conn
inChan chan []byte
outChan chan []byte
closeChan chan byte
mutex sync.Mutex
isClosed bool
}
func InitConnection(wsConn *websocket.Conn)(conn *Connection ,err error){
conn=&Connection{
wsConn:wsConn,
inChan:make(chan []byte,1000),
outChan:make(chan []byte,1000),
closeChan:make(chan byte,1),
}
go conn.readLoop()
go conn.writeLoop()
return
}
func (conn *Connection) ReadMessage()(data []byte,err error){
select {
case data=<-conn.inChan:
case <-conn.closeChan:
err=errors.New("connection is closed")
}
return
}
func (conn *Connection) WriteMessage(data []byte)(err error){
select {
case conn.outChan<-data:
case <-conn.closeChan:
err=errors.New("connection is closed")
}
return
}
func (conn *Connection) Close(){
//线程安全的Close,可重入
conn.wsConn.Close()
conn.mutex.Lock()
if !conn.isClosed {
close(conn.closeChan)
conn.isClosed=true
}
conn.mutex.Unlock()
}
func (conn *Connection) readLoop(){
var(
data []byte
err error
)
for{
if _,data,err=conn.wsConn.ReadMessage();err !=nil{
goto ERR
}
select {
case conn.inChan<-data:
case <-conn.closeChan:
goto ERR
}
}
ERR:
conn.Close()
}
func (conn *Connection) writeLoop(){
var (
data []byte
err error
)
for{
select {
case data=<-conn.outChan:
case <-conn.closeChan:
goto ERR
}
if err=conn.wsConn.WriteMessage(websocket.TextMessage,data);err!=nil{
goto ERR
}
}
ERR:
conn.Close()
}
首先定义一个结构体
type Connection struct {
wsConn *websocket.Conn
inChan chan []byte
outChan chan []byte
closeChan chan byte
mutex sync.Mutex
isClosed bool
}
wsConn websocket的长链接的实体
inChan 读数据的channel
outChan 写数据的channel
closeChan 链接关闭的channel
mutex 互斥锁
isClosed 链接关闭标识符
func InitConnection(wsConn *websocket.Conn)(conn *Connection ,err error){
conn=&Connection{
wsConn:wsConn,
inChan:make(chan []byte,1000),
outChan:make(chan []byte,1000),
closeChan:make(chan byte,1),
}
go conn.readLoop()
go conn.writeLoop()
return
}
初始化链接
readLoop 和writeLoop 循环从websocket中读取数据和写入数据
func (conn *Connection) ReadMessage()(data []byte,err error){
select {
case data=<-conn.inChan:
case <-conn.closeChan:
err=errors.New("connection is closed")
}
return
}
ReadMessage() 从inChan中读取数据
func (conn *Connection) WriteMessage(data []byte)(err error){
select {
case conn.outChan<-data:
case <-conn.closeChan:
err=errors.New("connection is closed")
}
return
}
WriteMessage(data []byte) 写入数据传递给outChan ,writeLoop 监听outChan并写入数据
func (conn *Connection) Close(){
//线程安全的Close,可重入
conn.wsConn.Close()
conn.mutex.Lock()
if !conn.isClosed {
close(conn.closeChan)
conn.isClosed=true
}
conn.mutex.Unlock()
}
mutex锁住关闭操作 ,避免重复循环关闭链接
关闭链接时,传递closeChan ,同时关闭readLoop 和writeLoop
func (conn *Connection) readLoop(){
var(
data []byte
err error
)
for{
if _,data,err=conn.wsConn.ReadMessage();err !=nil{
goto ERR
}
select {
case conn.inChan<-data:
case <-conn.closeChan:
goto ERR
}
}
ERR:
conn.Close()
}
func (conn *Connection) writeLoop(){
var (
data []byte
err error
)
for{
select {
case data=<-conn.outChan:
case <-conn.closeChan:
goto ERR
}
if err=conn.wsConn.WriteMessage(websocket.TextMessage,data);err!=nil{
goto ERR
}
}
ERR:
conn.Close()
}
通过outChan和inChan 传递信息,保证线程的安全。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 封装JDBC—非框架开发必备的封装类
- SpringBlade 2.3.2 发布,增加 OSS 封装及单元测试封装
- SpringBlade 2.3.2 发布,增加 OSS 封装及单元测试封装
- docker 封装 alinode
- 封装Apk签名工具
- axios封装笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Making Things See
Greg Borenstein / Make / 2012-2-3 / USD 39.99
Welcome to the Vision Revolution. With Microsoft's Kinect leading the way, you can now use 3D computer vision technology to build digital 3D models of people and objects that you can manipulate with g......一起来看看 《Making Things See》 这本书的介绍吧!