(b []byte)
| 152 | } |
| 153 | |
| 154 | func (this *ClientConn) Write(b []byte) (n int, err error) { |
| 155 | if len(b) == 0 { |
| 156 | return 0, nil |
| 157 | } |
| 158 | |
| 159 | if this.isDebugging { |
| 160 | this.lastWriteAt = fasttime.Now().Unix() |
| 161 | |
| 162 | defer func() { |
| 163 | if err != nil { |
| 164 | this.lastErr = fmt.Errorf("write error: %w", err) |
| 165 | } else { |
| 166 | this.lastErr = nil |
| 167 | } |
| 168 | }() |
| 169 | } |
| 170 | |
| 171 | // 设置写超时时间 |
| 172 | if !this.isPersistent && this.autoWriteTimeout { |
| 173 | var timeoutSeconds = len(b) / 1024 |
| 174 | if timeoutSeconds < 3 { |
| 175 | timeoutSeconds = 3 |
| 176 | } |
| 177 | _ = this.rawConn.SetWriteDeadline(time.Now().Add(time.Duration(timeoutSeconds) * time.Second)) // TODO 时间可以设置 |
| 178 | } |
| 179 | |
| 180 | // 延长读超时时间 |
| 181 | if this.isHTTP && !this.isPersistent && this.autoReadTimeout { |
| 182 | this.setHTTPReadTimeout() |
| 183 | } |
| 184 | |
| 185 | // 开始写入 |
| 186 | var before = time.Now() |
| 187 | n, err = this.rawConn.Write(b) |
| 188 | if n > 0 { |
| 189 | atomic.AddInt64(&this.totalSentBytes, int64(n)) |
| 190 | |
| 191 | // 统计当前服务带宽 |
| 192 | if this.serverId > 0 { |
| 193 | // TODO 需要加入在serverId绑定之前的带宽 |
| 194 | if !this.isNoStat || Tea.IsTesting() { // 环路不统计带宽,避免缓存预热等行为产生带宽 |
| 195 | atomic.AddUint64(&teaconst.OutTrafficBytes, uint64(n)) |
| 196 | |
| 197 | var cost = time.Since(before).Seconds() |
| 198 | if cost > 1 { |
| 199 | stats.SharedBandwidthStatManager.AddBandwidth(this.userId, this.userPlanId, this.serverId, int64(float64(n)/cost), int64(n)) |
| 200 | } else { |
| 201 | stats.SharedBandwidthStatManager.AddBandwidth(this.userId, this.userPlanId, this.serverId, int64(n), int64(n)) |
| 202 | } |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | // 如果是写入超时,则立即关闭连接 |
| 208 | if err != nil && os.IsTimeout(err) { |
| 209 | // TODO 考虑对多次慢连接的IP做出惩罚 |
| 210 | conn, ok := this.rawConn.(LingerConn) |
| 211 | if ok { |
nothing calls this directly
no test coverage detected