服务器端Go程序对长短链接的处理及运行参数的保存

论坛 期权论坛 脚本     
niminba   2021-5-23 03:01   1745   0

对长、短连接的处理策略(模拟心跳)
作为一个可能会和很多Client进行通讯交互的Server,首先要保证的就是整个Server运行状态的稳定性,因此在和Client建立连接通讯的时候,确保连接的及时断开非常重要,否则一旦和多个客户端建立不关闭的长连接,对于服务器资源的占用是很可怕的。因此,我们需要针对可能出现的短连接和长连接,设定不同的限制策略。
    针对短连接,我们可以使用golang中的net包自带的timeout函数,一共有三个,分别是:

复制代码 代码如下:

func (*IPConn) SetDeadline 
func (c *IPConn) SetDeadline(t time.Time) error 
 
func (*IPConn) SetReadDeadline 
func (c *IPConn) SetReadDeadline(t time.Time) error 
 
func (*IPConn) SetWriteDeadline 
func (c *IPConn) SetWriteDeadline(t time.Time) error 

    如果想要给服务器设置短连接的timeout,我们就可以这么写:

复制代码 代码如下:

netListen, err := net.Listen("tcp", Port) 
    Log("Waiting for clients") 
    for { 
        conn, err := netListen.Accept() 
        if err != nil { 
            continue 
        } 

 
        conn.SetReadDeadline(time.Now().Add(time.Duration(10) * time.Second)) 
    这里的三个函数都是用于设置每次socket连接能够维持的最长时间,一旦超过设置的timeout后,便会在Server端自动断开连接。其中SetReadline, SetWriteline设置的是读取和写入的最长持续时间,而SetDeadline则同时包含了 SetReadline, SetWriteline两个函数。
    通过这样设定,每个和Server通讯的Client连接时长最长也不会超过10s了~~

    搞定短连接后,接下来就是针对长连接的处理策略了~~
    作为长连接,由于我们往往很难确定什么时候会中断连接,因此并不能像处理短连接那样简单粗暴的设定一个timeout就可以搞定,而在Golang的net包中,并没有针对长连接的函数,因此需要我们自己设计并实现针对长连接的处理策略啦~
    针对socke长连接,常见的做法是在Server和Socket之间设计通讯机制,当两者之间没有信息交互时,双方便会定时发送数据包(心跳),以维持连接状态。

    这种方法是目前使用相对比较多的做法,但是开销相对也较大,特别是当Server和多个client保持长连接的时候,并发会比较高,考虑到公司的业务需求,我最后选择了逻辑相对简单,开销相对较小的策略:
    当Server每次收到Client发到的信息之后,便会开始心跳计时,如果在心跳计时结束之前没有再次收到Client发来的信息,那么便会断开跟Client的连接。而一旦在设定时间内再次收到Client发来的信息,那么Server便会重置计时器,再次重新进行心跳计时,直到超时断开连接为止。
下面就是实现该计时的代码:

复制代码 代码如下:

//长连接入口 
func handleConnection(conn net.Conn,timeout int) { 
 
    buffer := make([]byte, 2048) 
    for { 
        n, err := conn.Read(buffer) 
 
        if err != nil { 
            LogErr(conn.RemoteAddr().String(), " connection error: ", err) 
            return 
        } 
        Data :=(buffer[:n]) 
        messnager := make(chan byte) 
        postda :=make(chan byte) 
        //心跳计时 
        go HeartBeating(conn,messnager,timeout) 
        //检测每次Client是否有数据传来 
        go GravelChannel(Data,messnager) 
        Log( "receive data length:",n) 
   BY[YK][X\^WNB]\[YK[BIBB\[H X[[IB]\BI ]BB/#9-[:acy9. {B ]\H]]H[H\HX]]OHHYHX] HOi#yb-. O [9. yi." ]]\HXHYHLHB[SYHX\[[BB\[ [B\\\BB[HXZ[IB[Y[[XZ[IBl!)9a9a`j\9.+{/oBX\ N[XZX\[[B[ \H[[ XY[JY[IBX\\IBX\H[ ]X\]\]НY\[ JIBBNL BL B \HX\[ N\OH[ \HX\[ HBB][H \JHB9i!9a`B[ \[[Y[BB[YHH[[YK[ B[O\[[YJIBOZJBB[ \]NB[ HH[]JIB[Y[X\[ [Y[[ JIB[Y[OX[ IBZBBIBIB[L [[N BX\ V^[WOU[Y[IBIBB]\X\ IBIBc\9al:-[[9.+ym#yi&i9i!9/B ]BB/c9b99i."B B[Y[H M MML N MMK 0 HZZ[Z[[^][K NKYN M MMM X MLM  B
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP