ttps://bitbucket.org/tebeka/seamless是一个开源的反向代理项目,可将用户访问通过代理分流给多个后端服务器。可通过http接口动态增加删除后端服务。
项目主要文件有两个:seamless.go和backends.go,简单,易于阅读学习。
其中最主要的一个函数forward用于转发请求:
1
2 3 4 5 6 7 8 9 10 |
func forward
(local net.
Conn
, remoteAddr string
)
{
remote , err := net. Dial ( "tcp" , remoteAddr ) if err != nil { log. Printf ( "remote dial failed: %v\n" , err ) local. Close ( ) return } go io. Copy (local , remote ) go io. Copy (remote , local ) } |
io.Copy一句是精隨。
local和remote均是一个网络连接,类型为net.Conn,关于Conn接口的定,在Go官方源码中有:
1
2 3 4 5 6 7 8 9 10 |
io.Copy(dst Writer, src Reader),则实现从src复制到dst。
io.Copy的实现代码有:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
buf
:= make
(
[
]byte
,
32
*
1024
)
for { nr , er := src. Read (buf ) if nr > 0 { nw , ew := dst. Write (buf [ 0 :nr ] ) if nw > 0 { written += int64 (nw ) } if ew != nil { err = ew break } if nr != nw { err = ErrShortWrite break } } if er == EOF { break } if er != nil { err = er break } } return written , err |
可以看到调用了Read和Write方法,而这个方法刚好net.Conn中定义了。这就实现了将一个连接的数据复制到另一个连接。