client, err := rpc.Dial("tcp", "127.0.0.1:8088")
if err != nil {
log.Fatal("dialhttp: ", err)
}
defer client.Close()
客户端创建rpc连接client后,我怎么维护这个连接呢,因为我要维持这个长连接,没有数据发送时可以使用发送心跳来维持。我怎么监控服务端是否把我断开了,然后重连。
比较简单的办法:
服务端收到客户端的心跳包后回复,客户端收到回复后做标记表示已收到回复,客户端在下一次发送心跳包时先检查上一次的发送有没有收到回复,如果没有就认为连接已断开,发送心跳包的时间间隔根据应用场景做测试后来定,如果是实时性的就间隔短一点
在上面的情况下,服务端判断连接是否断开就很简单了:在每次Read之前通过`func (*TCPConn) SetReadDeadline`设置timeout为一个大于心跳时间间隔的合适值(例如2倍心跳间隔),如果Read返回的err表示是timeout就可以认为连接已断开
“需要轮询每个客户端的消息”, 这就没利用到goroutine的优势:来一个连接就用一个goroutine读取消息并处理,即使开它几百万个goroutine都没问题,既直观又高效
#3
更多评论
用一个map,为每一个客户端分配一个id,用这个id与服务器通信,然后用一个msg := make(chan string)来监听客户端消息,再用一个leaving := make(chan string)来监听客户端断开的消息,有客户端断开时,向leaving发送本客户端的id,服务端接收后,从map中释放该连接资源即可,当然这是典型的select场景,需要轮询每个客户端的消息,类似于c++的select或者poll,想用异步io,还要更麻烦些。
#2