[Go]基于Go语言的Web路由转发,多个网站共享一个端口(存在问题,已经抛弃,新解决方案请看新博客)
服务器上跑了很多的Web服务,但都是基于Golang自己写的,不能像IIS或者Apache一样共享端口和绑定域名,很多端口号自己又记不住
所以呢,我就利用端口转发技术,制作了这样一个Web路由
其主要原理就是将所有流量集中在一个端口,然后再将其通过域名转发至真正WebServer工作的端口
从而实现了域名指向一处服务器,而服务器又可以通过域名连接至与其对应的Web服务
其实在我的测试中,这个Web路由也可以进行网站镜像之类的服务,或者说直接将流量转发至其他服务器
下面是在我服务器上的测试,已经投入使用,暂时没用什么问题
这里是代码,其实也不多,就一百来行
package main import ( "bytes" "fmt" "io" "os" "log" "net" "strings" "regexp" "io/ioutil" "encoding/json" ) type Rule struct{ Domain string `json:Domain` Address string `json:Address` } type Config struct{ MainPort string `json:MainPort` Rules []Rule `json:Rules` } var myConfig Config func InitConfig(){ var Data,err = ioutil.ReadFile("config.json") if err != nil{ log.Println("Read Config File Error!") os.Exit(0) return } err = json.Unmarshal(Data,&myConfig) if err != nil{ log.Println("Read Config JSON Error!Please Check!") os.Exit(0) return } fmt.Println("Main Port:"+myConfig.MainPort) for i:=0;i<len(myConfig.Rules);i++{ fmt.Println("Domain: "+myConfig.Rules[i].Domain+" <----> "+myConfig.Rules[i].Address) } } func handleClientRequest(client net.Conn) { if client == nil { return } defer client.Close() var b [1024]byte n, err := client.Read(b[:]) if err != nil { log.Println(err) return } var method, url, HTTPv, address string fmt.Sscanf(string(b[:bytes.IndexByte(b[:], '\n')]), "%s%s%s", &method, &url, &HTTPv) address = GetAddress(string(b[:])) if address == "nil"{ fmt.Println("Unknow Domain") return } server, err := net.Dial("tcp", address) if err != nil { log.Println(err) return } if method == "CONNECT" { fmt.Fprint(client, "HTTP/1.1 200 Connection established\r\n\r\n") } else { server.Write(b[:n]) } go io.Copy(server, client) io.Copy(client, server) } func GetAddress(HTTPData string) string{ Lines := strings.Split(HTTPData,"\r\n") for i:=0;i<len(Lines);i++{ line := Lines[i] temp := strings.Split(line,": ") if strings.Compare(temp[0],"Host")==0{ for i:=0;i<len(myConfig.Rules);i++{ if strings.Compare(myConfig.Rules[i].Domain,temp[1])==0{ return myConfig.Rules[i].Address } } } } return "nil" } func compressStr(str string) string { if str == "" { return "" } reg := regexp.MustCompile("\\s+") return reg.ReplaceAllString(str, "") } func main() { log.SetFlags(log.LstdFlags|log.Lshortfile) InitConfig() l, err := net.Listen("tcp", ":"+myConfig.MainPort) if err != nil { log.Panic(err) } for { client, err := l.Accept() if err != nil { log.Panic(err) } go handleClientRequest(client) } }
下面是GitHub地址:https://github.com/leeli73/WebRouter
Config规则和几个Release都在该项目中