func tcpListener() { db := utils.DB log.Debug("tcp") go func() { if db == nil || db.DB == nil { for { db = utils.DB if db != nil && db.DB != nil { break } else { utils.Sleep(3) } } } tcpHost := db.GetTcpHost() log.Debug("tcpHost: %v", tcpHost) // включаем листинг TCP-сервером и обработку входящих запросов l, err := net.Listen("tcp", tcpHost) if err != nil { log.Error("Error listening: %v", err) panic(err) //os.Exit(1) } //defer l.Close() go func() { for { conn, err := l.Accept() if err != nil { log.Error("Error accepting: %v", err) utils.Sleep(1) //panic(err) //os.Exit(1) } else { go func(conn net.Conn) { t := new(tcpserver.TcpServer) t.DCDB = db t.Conn = conn t.HandleTcpRequest() }(conn) } } }() }() // Листенинг для чата go func() { listener, err := net.Listen("tcp", ":"+consts.CHAT_PORT) if err != nil { log.Error("Error listening: %v", err) panic(err) } defer listener.Close() for { conn, _ := listener.Accept() log.Debug("main conn %v\n", conn) log.Debug("conn.RemoteAddr() %v\n", conn.RemoteAddr().String()) go func(conn net.Conn) { buf := make([]byte, 4) _, err := conn.Read(buf) if err != nil { log.Debug("%v", err) return } // получим user_id в первых 4-х байтах userId := utils.BinToDec(buf) // и тип канала buf = make([]byte, 1) _, err = conn.Read(buf) if err != nil { log.Debug("%v", err) return } chType := utils.BinToDec(buf) log.Debug("userId %v chType %v", userId, chType) // мониторит входящие if chType == 0 { fmt.Println("chType 0", conn.RemoteAddr(), utils.Time()) utils.ChatMutex.Lock() utils.ChatInConnections[userId] = 1 utils.ChatMutex.Unlock() go utils.ChatInput(conn, userId) } // создаем канал, через который будем рассылать тр-ии чата if chType == 1 { re := regexp.MustCompile(`(.*?):[0-9]+$`) match := re.FindStringSubmatch(conn.RemoteAddr().String()) if len(match) != 0 { fmt.Println("chType 1", conn.RemoteAddr(), utils.Time()) // проверим, нет ли уже созданного канала для такого хоста if _, ok := utils.ChatOutConnections[userId]; !ok { fmt.Println("ADD", userId, conn.RemoteAddr(), utils.Time()) connChan := make(chan *utils.ChatData, 100) utils.ChatMutex.Lock() utils.ChatOutConnections[userId] = &utils.ChatOutConnectionsType{MessIds: []int64{}, ConnectionChan: connChan} utils.ChatMutex.Unlock() fmt.Println("utils.ChatOutConnections", utils.ChatOutConnections) utils.ChatTxDisseminator(conn, userId, connChan) } else { fmt.Println("SKIP", userId, conn.RemoteAddr(), utils.Time()) conn.Close() } } } }(conn) } }() }
func (d *daemon) chatConnector() { log.Debug("start chatConnector") maxMinerId, err := d.Single("SELECT max(miner_id) FROM miners_data").Int64() if err != nil { log.Error("%v", err) } if maxMinerId == 0 { maxMinerId = 1 } q := "" if d.ConfigIni["db_type"] == "postgresql" { q = "SELECT DISTINCT ON (tcp_host) tcp_host, user_id FROM miners_data WHERE miner_id IN (" + strings.Join(utils.RandSlice(1, maxMinerId, consts.COUNT_CHAT_NODES), ",") + ")" } else { q = "SELECT tcp_host, user_id FROM miners_data WHERE miner_id IN (" + strings.Join(utils.RandSlice(1, maxMinerId, consts.COUNT_CHAT_NODES), ",") + ") GROUP BY tcp_host" } hosts, err := d.GetAll(q, consts.COUNT_CHAT_NODES) if err != nil { log.Error("%v", err) } // исключим себя myTcpHost, err := d.Single(`SELECT tcp_host FROM miners_data WHERE user_id = ?`, myUserIdForChat).String() if err != nil { log.Error("%v", err) } fmt.Println("myTcpHost:", myTcpHost) // исключим хосты, к которым уже подключены var uids string for userId, _ := range utils.ChatOutConnections { uids += utils.Int64ToStr(userId) + "," } if len(uids) > 0 { uids = uids[:len(uids)-1] } existsTcpHost, err := d.GetList(`SELECT tcp_host FROM miners_data WHERE user_id IN (` + uids + `)`).String() if err != nil { log.Error("%v", err) } log.Debug("hosts: %v", hosts) for _, data := range hosts { host := data["tcp_host"] userId := utils.StrToInt64(data["user_id"]) if host == myTcpHost || utils.InSliceString(host, existsTcpHost) { continue } go func(host string, userId int64) { log.Debug("host: %v", host) log.Debug("userId: %d", userId) re := regexp.MustCompile(`(.*?):[0-9]+$`) match := re.FindStringSubmatch(host) log.Debug("match: %v", match) if len(match) != 0 { log.Debug("myUserIdForChat %v", myUserIdForChat) log.Debug("chat host: %v", match[1]+":"+consts.CHAT_PORT) chatHost := match[1] + ":" + consts.CHAT_PORT //chatHost := "192.168.150.30:8087" // проверим, нет ли уже созданных каналов для такого хоста if _, ok := utils.ChatOutConnections[userId]; !ok { // канал для приема тр-ий чата conn, err := net.DialTimeout("tcp", chatHost, 5*time.Second) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } else { log.Debug(conn.RemoteAddr().String(), conn) myUid := utils.DecToBin(myUserIdForChat, 4) log.Debug("myUid %x", myUid) n, err := conn.Write(myUid) log.Debug("n: %d", n) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } n, err = conn.Write(utils.DecToBin(1, 1)) log.Debug("n: %d", n) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } fmt.Println("connector ChatInput", conn.RemoteAddr(), utils.Time()) log.Debug("connector ChatInput %s %v", conn.RemoteAddr(), utils.Time()) utils.ChatMutex.Lock() utils.ChatInConnections[userId] = 1 utils.ChatMutex.Unlock() go utils.ChatInput(conn, userId) } // канал для отправки тр-ий чата conn2, err := net.DialTimeout("tcp", chatHost, 5*time.Second) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } else { log.Debug(conn2.RemoteAddr().String(), conn2) n, err := conn2.Write(utils.DecToBin(myUserIdForChat, 4)) log.Debug("n: %d", n) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } n, err = conn2.Write(utils.DecToBin(0, 1)) log.Debug("n: %d", n) if err != nil { log.Error("%v", utils.ErrInfo(err)) return } fmt.Println("connector ADD", userId, conn2.RemoteAddr(), utils.Time()) log.Debug("connector ADD %v %s %v", userId, conn2.RemoteAddr(), utils.Time()) connChan := make(chan *utils.ChatData, 100) utils.ChatMutex.Lock() utils.ChatOutConnections[userId] = &utils.ChatOutConnectionsType{MessIds: []int64{}, ConnectionChan: connChan} utils.ChatMutex.Unlock() fmt.Println("ChatOutConnections", utils.ChatOutConnections) utils.ChatTxDisseminator(conn2, userId, connChan) } } } }(host, userId) } }