Go语言 如果实现http重连?
来源:互联网 发布:十大最帅天刀捏脸数据 编辑:程序博客网 时间:2024/05/17 03:45
怎样做到每次使用一个连接发送和接收前就设置超时呢?我想了个办法是在Dial回调返回自己包装过的TimeoutConn,间接的调用真实的Conn,这样就可以再每次Read和Write之前设置超时时间了。
以下是修改后的实验代码:
//// How to set timeout for http.Get() in golang//package mainimport ( "io" "io/ioutil" "log" "net" "net/http" "sync" "time")type TimeoutConn struct { conn net.Conn timeout time.Duration}func NewTimeoutConn(conn net.Conn, timeout time.Duration) *TimeoutConn { return &TimeoutConn{ conn: conn, timeout: timeout, }}func (c *TimeoutConn) Read(b []byte) (n int, err error) { c.SetReadDeadline(time.Now().Add(c.timeout)) return c.conn.Read(b)}func (c *TimeoutConn) Write(b []byte) (n int, err error) { c.SetWriteDeadline(time.Now().Add(c.timeout)) return c.conn.Write(b)}func (c *TimeoutConn) Close() error { return c.conn.Close()}func (c *TimeoutConn) LocalAddr() net.Addr { return c.conn.LocalAddr()}func (c *TimeoutConn) RemoteAddr() net.Addr { return c.conn.RemoteAddr()}func (c *TimeoutConn) SetDeadline(t time.Time) error { return c.conn.SetDeadline(t)}func (c *TimeoutConn) SetReadDeadline(t time.Time) error { return c.conn.SetReadDeadline(t)}func (c *TimeoutConn) SetWriteDeadline(t time.Time) error { return c.conn.SetWriteDeadline(t)}func main() { client := &http.Client{ Transport: &http.Transport{ Dial: func(netw, addr string) (net.Conn, error) { log.Printf("dial to %s://%s", netw, addr) conn, err := net.DialTimeout(netw, addr, time.Second*2) if err != nil { return nil, err } return NewTimeoutConn(conn, time.Second*2), nil }, ResponseHeaderTimeout: time.Second * 2, }, } addr := StartTestServer() SendTestRequest(client, "1st", addr, "normal") SendTestRequest(client, "2st", addr, "normal") SendTestRequest(client, "3st", addr, "timeout") SendTestRequest(client, "4st", addr, "normal") time.Sleep(time.Second * 3) SendTestRequest(client, "5st", addr, "normal")}func StartTestServer() string { listener, err := net.Listen("tcp", ":0") if err != nil { log.Fatalf("failed to listen - %s", err.Error()) } wg := new(sync.WaitGroup) wg.Add(1) go func() { http.HandleFunc("/normal", func(w http.ResponseWriter, req *http.Request) { time.Sleep(1000 * time.Millisecond) io.WriteString(w, "ok") }) http.HandleFunc("/timeout", func(w http.ResponseWriter, req *http.Request) { time.Sleep(2500 * time.Millisecond) io.WriteString(w, "ok") }) wg.Done() err = http.Serve(listener, nil) if err != nil { log.Fatalf("failed to start HTTP server - %s", err.Error()) } }() wg.Wait() log.Printf("start http server at http://%s/", listener.Addr()) return listener.Addr().String()}func SendTestRequest(client *http.Client, id, addr, path string) { req, err := http.NewRequest("GET", "http://"+addr+"/"+path, nil) if err != nil { log.Fatalf("new request failed - %s", err) } req.Header.Add("Connection", "keep-alive") switch path { case "normal": if resp, err := client.Do(req); err != nil { log.Fatalf("%s request failed - %s", id, err) } else { result, err2 := ioutil.ReadAll(resp.Body) if err2 != nil { log.Fatalf("%s response read failed - %s", id, err2) } resp.Body.Close() log.Printf("%s request - %s", id, result) } case "timeout": if _, err := client.Do(req); err == nil { log.Fatalf("%s request not timeout", id) } else { log.Printf("%s request - %s", id, err) } }}
0 0
- Go语言 如果实现http重连?
- go语言实现http服务端与客户端
- GO语言HTTP代理服务器
- Go语言动态规划矩阵连乘
- 使用Go语言实现http服务端指定路径的文件.
- mysql_ping实现数据库重连
- Netty Client重连实现
- Netty Client重连实现
- Go语言Slice去重
- Go语言net/http 解读.
- go语言的http包
- 汉诺塔go语言实现
- GO语言实现selpg
- go语言实现九九乘法表
- mina2.0的重连实现
- ubuntu下实现ssh自动重连
- 初探和实现websocket心跳重连
- Python 实现断网自动重连
- 基于STM32F103RBT6 的CAN双机通讯成功案例工程下载
- 怎么让你的家庭电脑变身网站服务器(IT男成长记)
- 传智基础与加强day09(前段时间复习与回顾)
- 严重: Servlet.service() for servlet [jsp] in context with path [] threw exception [/addGoods.jsp(1,34)
- VC 目录、文件的相关操作
- Go语言 如果实现http重连?
- vi编辑器设置,sudo用户设置
- 字符串中取数字
- C#算数运算符重载
- Java基础知识——JNI入门介绍
- cocos2d-x触摸事件优先级
- 桥接模式及C++代码实现
- PKU 1020
- STL deque