예제 #1
0
파일: notandroid.go 프로젝트: dzyk/dcoin-go
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)
		}
	}()
}
예제 #2
0
파일: connector.go 프로젝트: dzyk/dcoin-go
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)
	}
}