Example #1
0
// Inizializzare il server in ascolto per le Sincronizzazione delle conversazioni
//
// "laddress string" indica su quali indirizza ascoltare e su quale porta
func StartServer(laddress string) {
	ln, err := net.Listen("tcp", laddress)
	logs.Log("Server in ascolto su: \"", laddress, "\"")
	if err != nil {
		logs.Error("Errore nell'aprire la connessione: ", err.Error())
		return
		//TODO handle error
	}

	//database.MainConv = database.NewConversation(database.ServerFakeUser) //duplicato!

	//canale := make(chan byte, 256)
	codaReadiness := make(chan *Client, 64)
	codaAccettazioni := make(chan *Client, 64)
	logs.AggiungiAzioneDiChiusura(func() {
		close(codaReadiness)
		close(codaAccettazioni)
	})

	go spedisci(codaAccettazioni, codaReadiness)

	var spegniti bool = false

	logs.AggiungiAzioneDiChiusura(func() {
		spegniti = true
		ln.Close()
	})

	for !spegniti {
		conn, err := ln.Accept()
		if spegniti {
			return
		}
		if err != nil {
			//TODO fare un pacchetto per la raccolta degli errori
			logs.Error("Tentativo di connessione non andato a buon fine: ", err.Error())
		}

		go func() {
			client, gestore := GestisciClient(conn)
			if client != nil {
				go gestore(codaReadiness)
				codaAccettazioni <- client
			} else {
				//L'handshaking non รจ andato a buon fine
				conn.Close()
			}
		}()

	}
}
// Inizializza tutte le operazioni necessarie per sul database
func init() {
	logs.Log("init del database")

	ServerFakeUser = new(User)
	ServerFakeUser.ID = 0
	ServerFakeUser.Username = "******"
	serverPassword := sha256.New()
	serverPassword.Write([]byte("toor"))
	ServerFakeUser.password = serverPassword.Sum([]byte{})

	err := CreateDataBaseSQL()
	if err != nil {
		logs.Error(err.Error())
	}

	//	MainConv = NewConversation(ServerFakeUser)
	err = Data.caricaConversazioni()
	if err != nil {
		logs.Error("Impossibile caricare le conversazioni vecchie\nmotivo: ", err.Error())
	}

	//	err = salvaUtente(ServerFakeUser)
	//	if err != nil {
	//		logs.Error("Impossibile salvare l'utente server nel database\nmotivo: ", err.Error())
	//	}()

	Data.CaricaUtentiSQL()
	if err != nil {
		logs.Error("Impossibile caricare gli utenti dal database\nmotivo: ", err.Error())
	}

	go func() {
		var spegniti bool = false
		logs.AggiungiAzioneDiChiusura(func() { spegniti = true })

		tk := time.NewTicker(10 * time.Minute)
		for !spegniti {
			<-tk.C
			err := MainConv.salvaTutteLeConversazioniSQL()
			if err != nil {
				logs.Error("Impossibile salvare tutti i post\nmotivo: ", err.Error())
			}
			logs.Log("salvate tutte le conversazioni sul database")
			//err := MainConv.salvaTuttiIPostSQL(&Data)
			//if err != nil {
			//	logs.Error("Impossibile salvare tutti i post\nmotivo: ", err.Error())
			//}
		}
		tk.Stop()
	}()
}
Example #3
0
// Inizializza la struttura dati del client e crea la funzione per gestire il client
// (da partire come goroutine)
func GestisciClient(conn net.Conn) (*Client, func(chan *Client)) {
	fmt.Print("Nuova connessione: ")
	fmt.Println(conn.RemoteAddr())

	client := NewClient(&conn)
	if client == nil {
		conn.Close()
		return nil, nil
	}

	return client, func(readiness chan *Client) {

		var spegniti bool = false

		logs.AggiungiAzioneDiChiusura(func() {
			spegniti = true
		})

		for !spegniti {
			_, size, err := client.stream.ReadRune()
			if err != nil {
				logs.Error("connessione interrotta: ", conn.RemoteAddr().String(), "\n\tmotivazione: ", err.Error())
				client.gestisciDisconnessione(database.MainConv)
				return
			}
			//			for i := 0; i < size; i++ {
			fmt.Printf("letto carattere di %v byte\n", size)
			err = client.stream.UnreadRune()
			if err != nil {
				logs.Error("impossibile fare UnreadByte: ", conn.RemoteAddr().String(), "\n\tmotivazione: ", err.Error())
				client.gestisciDisconnessione(database.MainConv)
				return
			}
			//			}

			readiness <- client
			<-client.blocco
		}

		(*client.conn).Close()
	}
}
Example #4
0
// Funzione che innesta tutta la procedura per il parsing di quello ricevuto
// dai client.
//TODO migliora la documentazione
func flasher(codaCiclica *list.List, readiness chan *Client) {
	tempoDaAspettare := 30 * time.Millisecond
	var lastActiveUser int = -1
	input := make(chan rune, 256)
	output := make(chan string, 256)
	logs.AggiungiAzioneDiChiusura(func() {
		close(input)
		close(output)
	})

	go gestisciTestoConversazione(input, output)

	// semplice funzione che rispedisce tutto quello che passa
	// dal canale di output sui socket delle connessioni
	go func() {
		for buffer := range output {
			for e := codaCiclica.Front(); e != nil; e = e.Next() {
				client := e.Value.(*Client)
				client.stream.WriteString(buffer)
				client.stream.Flush()
			}
		}
	}()

	var spegniti bool = false

	logs.AggiungiAzioneDiChiusura(func() {
		spegniti = true
	})

	for !spegniti {
		start := time.Now()

		quanti := len(readiness)

		for i := 0; i < quanti; i++ {
			clientAttivo := <-readiness
			var chiSonoString string

			if lastActiveUser != clientAttivo.user.ID {
				chiSonoString = strings.Join([]string{"\\U", strconv.Itoa(clientAttivo.user.ID), "\\"}, "")
				lastActiveUser = clientAttivo.user.ID
				database.MainConv.UtenteAttivo = lastActiveUser
			} else {
				chiSonoString = ""
			}
			chiSonoSSize := len(chiSonoString)

			//leggi cosa spedire
			var daLeggere int = clientAttivo.stream.Reader.Buffered()
			buffer := make([]rune, chiSonoSSize, daLeggere+chiSonoSSize)
			var err error
			var letto rune
			var size, i, j int
			for i, j = chiSonoSSize, 0; i < chiSonoSSize+daLeggere && j < daLeggere; i++ {
				letto, size, err = clientAttivo.stream.ReadRune()
				buffer = append(buffer, letto)
				j += size
				//fmt.Printf("#####size:_%v_ carattere:_%v_%v_\n",strconv.Itoa(size),string(buffer[i]),buffer[i])
				if err != nil {
					//TODO gestisci errore
					logs.Error("Errore nel leggere dalla rete")
					clientAttivo.blocco <- 1 //TODO dovresti chiudere il canale e tutto quanto
					clientAttivo.gestisciDisconnessione(database.MainConv)
					break
				}
			}
			clientAttivo.blocco <- 0

			//prepara il buffer da spedire
			for i := 0; i < chiSonoSSize; i++ {
				buffer[i] = []rune(chiSonoString)[i]
			}
			//			buffer = buffer[:i]

			//spedisci
			for i := 0; i < len(buffer); i++ {
				input <- buffer[i]
			}
		}

		duration := time.Since(start)
		if duration <= tempoDaAspettare {
			time.Sleep(tempoDaAspettare - duration)
		}
	}
}
Example #5
0
// Funzione che inizializza tutte le cose necessarie per collegare il
// database SQL, e lo collega
func CreateDataBaseSQL() error {
	var err error

	db, err = sql.Open("postgres", "dbname=thinkzoneDB user=thinkzone")
	if err != nil {
		logs.Error("Impossibile aprire il database")
		return err
	}

	/*
		for i := range createDbSqlScript {
			_, err = db.Exec(createDbSqlScript[i])
			if err != nil {
				if "result error: ERROR:  relation \"t_user\" already exists\n" != err.Error() {
					logs.Error("Impossibile creare le tabelle del database\nmotivo: _", err.Error(), "_")
					return err
				}
				break
			}

		}
	*/

	insertUserOp, err = db.Prepare(insertUser)
	if err != nil {
		//		logs.Error("Impossibile salvare gli utenti nel database\nmotivo: ", err.Error())
		return err
	}

	insertPostOp, err = db.Prepare(insertPost)
	if err != nil {
		//		logs.Error("Impossibile creare i post nel database\nmotivo: ", err.Error())
		return err
	}

	updatePostOp, err = db.Prepare(updatePost)
	if err != nil {
		//		logs.Error("Impossibile salvare i post nel database\nmotivo: ", err.Error())
		return err
	}

	insertConvOp, err = db.Prepare(insertConv)
	if err != nil {
		//		logs.Error("Impossibile salvare le conversazioni nel database\nmotivo: ", err.Error())
		return err
	}

	updateConvOp, err = db.Prepare(updateConv)
	if err != nil {
		return err
	}

	logs.AggiungiAzioneDiChiusura(func() {
		if insertUserOp != nil {
			insertUserOp.Close()
		}
		if insertConvOp != nil {
			err := MainConv.salvaTutteLeConversazioniSQL()
			if err != nil {
				logs.Error("Impossibile salvare tutti i post\nmotivo: ", err.Error())
			}
			insertConvOp.Close()
		}
		if insertPostOp != nil {
			insertPostOp.Close()
		}
		if updatePostOp != nil {
			updatePostOp.Close()
		}
		if updateConvOp != nil {
			updateConvOp.Close()
		}
		return
	})

	return nil

}