Go——处理用户连接超时
Posted cnloop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go——处理用户连接超时相关的知识,希望对你有一定的参考价值。
所谓超时,就是一段时间用户没有做出任何操作,这里需要了解 select
select
select 用法与 switch 语言非常类似,由 select 开始一个新的选择块,每个选择条件由 case 语句来描述
case 语句里必须是一个 IO 操作
select语句中,会按顺序从头至尾评估每一个发送和接收的语句,如果其中的任意一语句可以继续执行(即没有被阻塞),那么就从那些可以执行的语句中任意选择一条来使用
如果 case 条件中都是阻塞的,那么 select 就会走 default 语句,没有 default 语句就会处于一直等待状态,直到任意一条 case 条件成立
一般不建议写 default,写了话,走 default 的概率太大
select 一般与 for 循环搭配使用,
超时操作
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for {
<-ch1
fmt.Println("get ch1")
}
}()
go func() {
for {
<-ch2
fmt.Println("get ch2")
}
}()
for {
select {
case ch1 <- 1:
case ch2 <- 2:
case <-time.After(time.Second * 1):
fmt.Println("tiem out .................")
}
}
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go func() {
for {
<-ch1
fmt.Println("get ch1")
}
}()
go func() {
for {
<-ch2
fmt.Println("get ch2")
}
}()
for {
select {
case ch1 <- 1:
case ch2 <- 2:
case <-time.After(time.Microsecond * 50):
fmt.Println("tiem out .................")
}
}
}
第一段代码最后输出结果要么是
get ch1
,要么是get ch2
,到最后都没看到time out ...
,这是为什么?第二段代码最后输出结果是打印多次
time out ....
,这是为什么?回过头看一下 select 的定义,其中有一句话是这样的:评估每一条 case 语句,任意选择一条未阻塞的语句执行
第一段代码 ch1、ch2 将数据发送到下游管道的时间,是明显短于定时器 1 秒,此时定时器相对于它们是处于阻塞状态的
第二段代码 ch1、ch2、tiem 都将会被 select 考虑,因为 ch1、ch2 管道的流动速度不是每次都比定时器的 50 微秒快的
实际运用
例如聊天室,当客户端连接到服务器,此时我们就开一个协程,基本代码如上,for 循环里面利用 select 不断监听管道流动,定时器时间为 20 秒
20 秒钟内,其他管道都处于阻塞状态,也就是没有客户数据的流入,那么 select 将会执行定时器内的操作,操作大多是 return,结束循环,触发 defer,关闭 conn 连接
以上是关于Go——处理用户连接超时的主要内容,如果未能解决你的问题,请参考以下文章