There is the following code that implements the simplest case of a load balancer.

main

package main func main() { server := HTTPServer{} server.RunServer("8082") } 

httpServer

 package main import ( "github.com/labstack/echo" "github.com/labstack/echo/engine/standard" "strings" "fmt" "time" ) type HTTPServer struct { srvTcp TCPServer srvWs TCPServer } func (c HTTPServer) RunServer(port string) { e := echo.New() go c.srvTcp.Listen("8081") go c.srvWs.Listen("8083") time.Sleep(time.Second * 10000) //TODO: e.GET("/getSocket", func) должен возвражать ip:port предпочтительного сервера e.GET("/getSocket", func(q echo.Context) error { response := "HTTP/1.1 200 OK\r\n\r\n" + c.srvTcp.getBestModule() return q.String(200, response) }) //TODO: e.GET("/getWebSocket", func) аналогично для вебСокета e.GET("/getWebSocket", func(q echo.Context) error { //response := "HTTP/1.1 200 OK\r\n\r\n" + c.srvWs.getBestModule() fmt.Println(c) response := c.srvWs.getBestModule() return q.String(200, response) }) //TODO: e.GET("/getStats", func) получение статов всех серверов (socket/webSocket), для сбора статистики Колей e.GET("/getStats", func(q echo.Context) error { response := []string{"HTTP/1.1 200 OK\r\n\r\n", "TCP:\r\n", c.srvTcp.getStatistics(), "\r\n________________\r\nWS:\r\n", c.srvWs.getStatistics()} return q.String(200, strings.Join(response, "")) }) e.Run(standard.New(":" + port)) } 

TCPServer

 package main import ( "os" "fmt" "net" "strings" "strconv" ) const ( CONN_HOST = "localhost" CONN_PORT = "3333" CONN_TYPE = "tcp" ) type TCPServer struct { Port string Clients []Client } func (c TCPServer) Listen(port string) { // начинаем слушать порт c.Port = port fmt.Println("TCP-server listen on port ", port) l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+ port) if err != nil { fmt.Println("Error listening:", err.Error()) os.Exit(1) } // закрываем после окончания работы defer l.Close() for { // ждем подключение conn, err := l.Accept() if err != nil { fmt.Println("Error accepting: ", err.Error()) os.Exit(1) } // отдаем дескриптор клиенту newClient := Client{} //нужно ли присваивание не помню fmt.Println(len(c.Clients)) c.Clients = append(c.Clients, newClient) fmt.Println(len(c.Clients)) go newClient.ListenDescriptor(conn) //go handleRequest(conn) } } func (c TCPServer) getBestModule() string { fmt.Println("Get best module") //TODO: выбор модуля и передача его ip:port fmt.Println(len(c.Clients)) fmt.Println(c) c.DeleteDeadClients() if c.Clients !=nil { bestClient := c.Clients[0] for _, client := range c.Clients { if client.ConnectionCount < bestClient.ConnectionCount { bestClient = client } } return bestClient.ModuleIP + ":" + bestClient.ModulePort } return "" } func (c TCPServer) getStatistics() string { fmt.Println("Get statistics") //TODO: вернуть статистику c.DeleteDeadClients() temp := []string{} temp = append(temp, "Modules count: ") temp = append(temp, strconv.FormatInt(int64(len(c.Clients)), 10)) temp = append(temp, "\r\n") var summConnections int64 = 0 for _, client := range c.Clients { temp = append(temp, client.ModuleIP) temp = append(temp, ":") temp = append(temp, client.ModulePort) temp = append(temp, " - clients: ") temp = append(temp, strconv.FormatInt(client.ConnectionCount, 10)) temp = append(temp, "; kiosks: ") temp = append(temp, strconv.FormatInt(client.KiosksCount, 10)) temp = append(temp, "; terminals: ") temp = append(temp, strconv.FormatInt(client.TerminalsCount, 10)) temp = append(temp, "; undefined: ") temp = append(temp, strconv.FormatInt(client.UndefinedCount, 10)) temp = append(temp, "\r\n") summConnections += client.ConnectionCount } temp = append(temp, "\r\n summ of connectins: ") temp = append(temp, strconv.FormatInt(summConnections, 10)) return strings.Join(temp, "") } func (c TCPServer) DeleteDeadClients() { fmt.Println("Deleting dead connections") //TODO: удалить клиентов которые отвалились или пмерли for index, client := range c.Clients { if client.Alive == false { c.Clients = append(c.Clients[:index], c.Clients[index+1:]...) } } } 

ClientTCP

 package main import ( "net" "fmt" "strings" "strconv" ) type Client struct { ID int Alive bool Connection net.Conn ModuleIP string ModulePort string ModuleName string ConnectionCount int64 KiosksCount int64 TerminalsCount int64 UndefinedCount int64 } func (c Client) ListenDescriptor(conn net.Conn) { fmt.Println("Listening connection", conn) //TODO: слушаем соединение с клиентом c.Connection = conn c.Alive = true for { // Make a buffer to hold incoming data. buf := make([]byte, 1024) // Read the incoming connection into the buffer. len, err := conn.Read(buf) if err != nil { fmt.Println("Client connection error") break } // Send a response back to person contacting us. c.deserializeData(buf[:len]) //conn.Write([]byte("Message received.\n")) // Close the connection when you're done with it. } c.Alive = false fmt.Println("Close connection ", conn) conn.Close() } func (c Client) deserializeData (data []byte) { fmt.Println("Deserialize data from client") //TODO: разогбрать данные от клиента и записть их куда следует //TODO: ниже идет какой-то треш, наверное стоит его переделать s := string(data) temp := strings.Split(s, "\n") fmt.Println(temp) c.ModuleIP = temp[0] c.ModulePort = temp[1] c.ModuleName = temp[2] c.ConnectionCount, _ = strconv.ParseInt(temp[3], 10 , 64) c.KiosksCount, _ = strconv.ParseInt(temp[4], 10 , 64) c.TerminalsCount, _ = strconv.ParseInt(temp[5], 10 , 64) c.UndefinedCount, _ = strconv.ParseInt(temp[6], 10 , 64) } func (c Client) GetConnection () net.Conn { return c.Connection } 

The problem is as follows. When you try to knock on / getWebSocket or / getSocket returns nothing, because the clients array is empty. It feels like I'm turning to the wrong object.

  • And yes, the client is already connected to this TCPServer and quite the same sends the data and they parse and output to the console - Anton Afanasyev
  • The question is no longer relevant. The github.com/labstack/echo/engine/standard package does not exist, and github.com/labstack/echo uses the outdated golang.org/x/net/context . I recommend to contact the author of the package, or replace it with something else. - Ivan Black

0