C# Chat Programm (Text an MySQL Datenbank übergeben)

Krabbelfiechle

Cadet 2nd Year
Registriert
März 2014
Beiträge
16
Hallo alle miteinander,

Ich bestreite zurzeit meine Ausbildung zur Fachinformatikerin und versuche gerade meine Skills was C# und die Datenbankanbindung angeht zu erweitern :)

Ich bin dabei ein Chat-Programm in C# zu Programmieren über welches man innerhalb eines Unternehmen untereinander Kommunizieren kann.

Nun habe ich 2 TextBoxen angelegt und möchte den Text den der Benutzer schreibt über einen Klick auf den Button an die Datenbank übergeben.
Mit dem Benutzernamen des PC's und natürlich auch mit der Information an welchen Empfänger - in diesem Fall auch der Benutzername des anderen PC'S - sowie um welche Uhrzeit dieser Text gesendet worden ist.
Dieser Text den der eine Benutzer gesendet hat soll dann direkt in die Tabelle eingefügt werden mit allen Informationen und der Empfänger soll die Nachricht direkt darauf Empfangen. ( Habe ein Bild von meiner Tabelle angefügt )

Ich habe mir vorgestellt für jeden Gesendeten Text eine neue Zeile in dieser Tabelle anzulegen und dass das Programm alle 2-3 Sekunden nachschaut ob für ihn eine neue Nachricht vorhanden ist.

Da ich aber nicht weis wie genau ich den Text an die Datenbank übergeben kann mit all diesen Informationen wende ich mich an euch! Die Datenbank ist schon verbunden und kann den Benutzernamen auslesen dies macht er sobald man das Programm startet.

Würde mich über Hilfe sehr freuen :)

MFG
Krabbelfiechle :evillol:
 

Anhänge

  • Datenbank.PNG
    Datenbank.PNG
    2,1 KB · Aufrufe: 424
  • Chat.PNG
    Chat.PNG
    164,6 KB · Aufrufe: 517
Guten Morgen und Herzlich willkommen bei Computerbase!

Bezüglich deiner Verbindung zu MySQl solltes du das hier befolgen


Um dich mit der mySql Datenbank zu verbinden brauchst du die MySql.dll. Diese bindest du in dein Projekt ein.
Mit hilfe dieser Baust du die Verbindung auf und kannst dann Inserts/Querys damit machen.
z.b.

Select * from Tasttabelle where Name = 'TestName'; (Man beachte bei strings die " ' " !)

Als Chatserver würde ich dir jedoch etwas anderes Vorschlagen.

Du hast einen zentralen Knotenpunkt(Server) wo du die nachrichten empfängst. Anschließend sendest du diese wieder an alle zurück.
Dies kannst du mit NetMQ ganz easy implementieren.(Kannst mich gerne dann per PN anschreiben,dann schick ich dir ein funktionierendes Beispielcode).

der Server kann ja dann parallel auch Einträge in einer Datenbank machen :)
 
Huhu,

Ich habe das Beispiel so vorgegeben bekommen von meinem Mentor da er mir das wohl beibringen möchte mit der Datenbank. Wie dem auch sei muss ich mich da halt irgendwie durchkämpfen da ich das gegebenenfalls wohl auch Präsentieren soll :)

Ich hätte es sonst auch anders gemacht, jedoch werde ich später genau diese Datenbankanbindungen öfters brauchen.
Ich denke ich werde wohl den INSERT Befehl brauchen um dann in die Tabelle etwas eintragen zu lassen wenn ich es noch richtig in Erinnerung habe. Mit der ersten Datenbankverbindung frage ich ja nur ab ob in der Tabelle User der Benutzername des PC's schon vorhanden ist danach schließe ich die Verbindung zur Datenbank wieder.
Also werde ich diese Verbindung später wieder aufbauen müssen um die Informationen einzufügen.
 
Ja,wenn nur mit einer Db arbeitest ist es dann doch relativ einfach.
du Brauchst zwei Tabellen:
1.Benutzer(benutzername,pw)
2.Nachrichten(id,text,benutzer,zeitpunkt)

Beim Programmstart machst du ein Query auf die Benutzer DB.
Wenns passt holst du dir die nachrichten der letzten 2 min.(select * from nachrichten where zeitpunkt < 'Datetime.UTC.Now').

diese liest du dann aus und machst sie zu einem String und fügst es einer List<string> hinzu.

Wenn du ein konkretes Beispiel brauchst,sagst bescheid. Ist schnell gemacht ^^
 
Unter System.Data.ODBC findest du alles, was du benötigst, um dich mit einer MySQL Datenbank zu verbinden. (Vorausgesetzt ist die Installation eines MySQL ODBC Treibers)

OdbcConnection lokaleDB;
lokaleDB = new OdbcConnection(@"Driver={MySQL ODBC 5.2 ANSI Driver};Server=127.0.0.1;PORT=3306;USER=root;PASSWORD=");

OdbcCommand command; //Diesem Objekt wird die Query übergeben und es wird zur Ausfühung benutzt. //Ist alles sehr gut in der MSDN erklärt
command = new OdbcCommand();
command.Connection = lokaleDB;

OdbcDataAdapter dataadabter; //Den Dataadabter kannst du verwenden, um das Ergebnis einer Query in eine Tabelle zu schreiben. (System.Data.DataTable)
dataadabter = new OdbcDataAdapter();
dataadabter.SelectCommand = cmd;

Hier ist ein Beispiel für eine Funktion, um aus einer Tabelle eine Query zu erstellen, die "command" übergeben wird, um sie in die Datenbank einzufügen: (Alternativ geht es auch alles mit dem Adabter: die Möglichkeiten dazu sind hier alle erklärt http://msdn.microsoft.com/de-de/library/ms171935.aspx )

Code:
public static string InsertMySQL(DataTable dt, string TableName)
        {
            //INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
            StringBuilder Query = new StringBuilder();
            Query.Append("INSERT INTO " + TableName + " (");
            int count = 0;
            foreach (DataColumn column in dt.Columns)
            {
                if (count != 0) { Query.Append(","); }
                Query.Append(column.ColumnName);
                count++;
            }
            Query.Append(") VALUES");
            int count2 = 0;
            foreach (DataRow row in dt.Rows)
            {
                if (count2 != 0) { Query.Append(","); }
                count = 0;
                foreach (DataColumn column in dt.Columns)
                {
                    if (count == 0) { Query.Append("("); }
                    else { Query.Append(","); }
                    Query.Append("'" + row[column.ColumnName].ToString() + "'");
                    count++;
                }
                Query.Append(")");
                count2++;
            }
            if (dt.Columns.Count > 1)
            {
                Query.Append(" ON DUPLICATE KEY UPDATE ");
            }
            count = 0;
            count2 = 0;

            foreach (DataColumn column in dt.Columns)
            {
                if (count2 > 1) { Query.Append(", "); }
                if (count != 0)
                {
                    Query.Append(column.ColumnName + " = VALUES (" + column.ColumnName + ")");
                }
                count++;
                count2++;
            }
            Query.Append(";");
            return Query.ToString();
        }


command.CommandText = InsertMySQL(Table, TableNameMySQLDatabase);
command.ExecuteNonQuery();
 
Zuletzt bearbeitet:
matias schrieb:
Ja,wenn nur mit einer Db arbeitest ist es dann doch relativ einfach.
du Brauchst zwei Tabellen:
1.Benutzer(benutzername,pw)
2.Nachrichten(id,text,benutzer,zeitpunkt)

Beim Programmstart machst du ein Query auf die Benutzer DB.
Wenns passt holst du dir die nachrichten der letzten 2 min.(select * from nachrichten where zeitpunkt < 'Datetime.UTC.Now').

diese liest du dann aus und machst sie zu einem String und fügst es einer List<string> hinzu.

Wenn du ein konkretes Beispiel brauchst,sagst bescheid. Ist schnell gemacht ^^

Ich könnte mal ein Beispiel brauchen... auch wenn ich nicht der TE bin hat mich das ganze neugierig gemacht.....=)
 
Das würde mich auch sehr interessieren! Allerdings habe ich in meiner Tabelle Benutzer nur den Benutzernamen sowie den Vor und Nachnamen und den Status also Online oder Offline ein Passwort wird hier nicht abgefragt da ich davon ausgehe dass sich der Benutzer ohnehin an seinem PC am Arbeitsplatz angemeldet hat.
 
Alles klar. Im laufe des Tages habt ihr dann ein Beispiel ;)
Ergänzung ()

Datenbank Struktur

Benutzer
int Id
string Benutzer
boolean Online

Nachrichten
int MessageId
string MessageText
string SenderName
DateTime SendTime



Start - Klasse

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChatProgram
{
	public class StartClass
	{
		private DataBase _databaseHelper;
		private User _currentuser;

		private void OperateWithUser(string userName)
		{
			_databaseHelper = new DataBase();

			if (CheckUserName(userName))
			{
				_databaseHelper.SetUserOnline(_currentuser);
			}
			
		}

		private List<Message> QueryAfterLastMessages()
		{
			return _databaseHelper.QueryLastMessages(DateTime.UtcNow);
		}

		private bool CheckUserName(string userName)
		{
			_currentuser = _databaseHelper.CheckUser(userName);
			if (_currentuser == null)
			{
				return false;
			}
			else
			{
				return true;
			}
			
		}


	}
}


Benutzer - Klasse

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChatProgram
{
	public class User
	{
		public int ID { get; set; }
		public string UserName { get; set; }
		public bool Online { get; set; }

	}
}


Nachrichten - Klasse

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChatProgram
{
	public class Message
	{
		public int MessageId { get; set; }
		public string MessageText { get; set; }
		public string SenderName { get; set; }
		public DateTime SendTime { get; set; }
	}
}


DataBase - Klasse

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql;

namespace ChatProgram
{
	using MySql.Data.MySqlClient;

	public class DataBase
	{
		public User CheckUser(string userName)
		{
			try
			{
				conn = new MySql.Data.MySqlClient.MySqlConnection();
				conn.ConnectionString = myConnectionString;
				conn.Open();
				var queryString = "Select * from Benutzer where BenutzerName ='" + userName + "';";
				MySqlCommand cmd = new MySqlCommand(queryString, conn);

				MySqlDataReader dataReader = cmd.ExecuteReader();

				var user = new User();
				while (dataReader.Read())
				{
					
					user.ID = dataReader.GetInt32(0);
					user.UserName = dataReader.GetString(1);
					user.Online = dataReader.GetBoolean(2);
				}

				dataReader.Close();
				conn.Close();

				return user;
			}
			catch (Exception)
			{
				
				throw;
			}
		}


		private string myConnectionString = "server=127.0.0.1;" + "uid=root;" + "pwd=12345;" + "database=test;";
		private MySql.Data.MySqlClient.MySqlConnection conn;

		public void SetUserOnline(User user)
		{
			try
			{
				conn = new MySql.Data.MySqlClient.MySqlConnection();
				conn.ConnectionString = myConnectionString;
				conn.Open();
				var updateString = "UPDATE Benutzer SET Online=" + user.Online + " WHERE BenutzerID=" + user.ID;
				MySqlCommand cmd = new MySqlCommand(updateString, conn);
				cmd.ExecuteNonQuery();
				conn.Close();
			}
			catch (Exception)
			{

				throw;
			}
		}

		internal List<Message> QueryLastMessages(DateTime dateTime)
		{
			try
			{
				conn = new MySql.Data.MySqlClient.MySqlConnection();
				conn.ConnectionString = myConnectionString;
				conn.Open();
				var queryString = "Select * from Nachrichten where CreatedAt >'" + dateTime.Year + "-" + dateTime.Month + "-" + dateTime.Day + " " + dateTime.Hour + ":" + dateTime.Minute + ":" + dateTime.Second + "';";
				MySqlCommand cmd = new MySqlCommand(queryString, conn);

				MySqlDataReader dataReader = cmd.ExecuteReader();

				var messages = new List<Message>();
				while (dataReader.Read())
				{
					var message = new Message();

					message.MessageId = dataReader.GetInt32(0);
					message.MessageText = dataReader.GetString(1);
					message.SenderName = dataReader.GetString(2);
					message.SendTime = Convert.ToDateTime(dataReader.GetValue(2));
					messages.Add(message);
				}

				dataReader.Close();
				conn.Close();

				return messages;
			}
			catch (Exception)
			{

				throw;
			}
		}
	}
}



Dieser Code kann Fehler enthalten und soll euch nur die Grundlegende Idee geben :)
 
Mach es doch bitte gleich richtig, mit den Feldern Sender und Empfänger (das Beispiel soll sicher ausbaufähig sein).

Das Konzept mit der Datenbank ist übrigens nicht veraltet, sondern Standard.
In heutigen Messengern liegt die DB nur meistens auf den Clients (sqlite o.a.), trotzdem ist sie da ;)

@matias
Dein Beispiel zeigt zwar einen schönen Stil auf, für Anfänger ist dies jedoch um so verwirrender (hast wohl ne weile auf C gemacht :))

mfg,
Max
 
@matias:

Schönes Beispiel, der TE sollte jedoch drauf achten, dass einige Fehler in den Select Statements sind. Denn dort wird "BenutzerName", "CreatedAt" und "BenutzerID" angesprochen, obwohl es die in der Datenbank-Struktur nicht gibt.
Aber das sind nur kleine Fehler und es soll ja auch nur als Beispiel dienen.
 
@max_1234
Hab mit C# angefangen und dabei geblieben ^^.

@apnotix
Ja,wie gesagt,sollte als kleines Beispiel dienen. Hab das in 20 min runter geschrieben,da die Zeit doch ein wenig gedrängt hat:)
 
Bitte ein aktuelles Buch kaufen. Das hier vorgestellte Beispiel ist anfällig für Sql Injection. Man sollte sich sowas von Anfang an korrekt aneignen...
 
oiisamiio schrieb:
Bitte ein aktuelles Buch kaufen. Das hier vorgestellte Beispiel ist anfällig für Sql Injection. Man sollte sich sowas von Anfang an korrekt erlernen...

Richtig, das Beispiel ist auch wirklich nicht schwer, lässt sich alles mit ein paar Minuten Google lösen (SQL queries).
Der Rest ist auch nur "sporadisches Abfragen mit Sleep o. Timer Klasse" und eben das Anzeigen der Resultate ....

Für den produktiven Einsatz würde man noch ein PHP-Skript vor den SQL-Server schalten und eine dauerhafte Verbindung damit herstellen, wobei das PHP-Skript in diesem Fall neue Messages automatisch an die Ziel-Clients weiterreicht.
 
Ja,wenn es in einer Webseite laufen würde wäre die Gefahr deutlich größer als in einem
UI wo man in code behind die abfragen macht.
Wo genau sollte das Problem sein @ oiisamiio?
Der Benutzername wird ausgelesen aus dem aktuell angemeldeten namen von Windows.
Die Nachricht wird aus einer Textbox eingelese und man kann dann ggf alle ' durch ´ ändern. Somit kann man nicht wirklich viel anfangen da es entweder ein Syntaxerror gibt oder ein MySql Exception.

@max_1234
Die anforderung war ja,dass man die Sachen in eine DB schreibt und die wieder ausließt via C# und WPF/oder Windows Forms.


SQL Inejctions
Code:
string spalte2Wert = "Mein Wert";
SqlCommand cmd = new SqlCommand("SELECT spalte1 FROM tabelle WHERE spalte2 = @spalte2Wert;");
cmd.Parameters.AddWithValue("@spalte2Wert", spalte2Wert);
 
Zuletzt bearbeitet:
Ich habe mein Problem nun so gelöst :

Code:
private void button1_Click(object sender, EventArgs e)
        {
            MySqlConnection connection = new MySqlConnection(myConnectionString);
            MySqlCommand kommando = connection.CreateCommand();
            kommando.CommandText = "INSERT INTO techchat.nachrichten (Text,Sender,Empfaenger,Zeitpunkt) VALUES ('" + textBox1.Text + "','" + Ich + "','" + empfaenger + "',now())";
            MySqlDataReader leser;
            connection.Open();
            kommando.BeginExecuteNonQuery();
            textBox1.Clear();
        }

public void Aufruf(string benutzer )
        {
            this.Show();
            empfaenger = benutzer;
            this.Text = "TecChat - " + empfaenger;
            
            MySqlConnection connection = new MySqlConnection(myConnectionString);
            MySqlCommand kommando = connection.CreateCommand();
            kommando.CommandText = "SELECT Text, Zeitpunkt, gelesen FROM techchat.nachrichten WHERE Empfaenger = '" + empfaenger + "'";
            MySqlDataReader leser;
            connection.Open();
            leser = kommando.ExecuteReader();
            string Text;
            string Zeitpunkt;
            string Ausgabe = "";

            while (leser.Read())
            {
                Text = leser.GetValue(0).ToString();
                Zeitpunkt = leser.GetValue(1).ToString();
                Ausgabe = Ausgabe + "< " + Zeitpunkt + " >   " + Text + Environment.NewLine;
            }
            textBox2.Text = Ausgabe;

            kommando.CommandText = "UPDATE techchat.nachrichten SET gelesen = 1 WHERE gelesen = 0 and Empfaenger ='"+ empfaenger +"'";
            kommando.BeginExecuteNonQuery();
            
        }

Dadurch wird der Text den ich an den Empfänger übertrage in die Datenbank eingetragen und meine TextBox in die ich den Text geschrieben habe wieder geleert.
Dann soll allerdings der Aufruf alle 5 Sekunden durchgeführt werden! Daran bin ich derzeit noch am knabbern weil ich nicht weis ich diese alle 5 Sekunden ausführen lassen kann. Hat jemand dafür vielleicht noch eine Lösung ?
 
Durch die Textbox ist es möglich beliebige Transaktion an die Datenbank zu senden. Warum sollte man es nicht gleich richtig lernen? Wer sich falsches Wissen aneignet läuft Gefahr, dieses in anderen Projekten zu übernehmen...
 
@Krabbelfiechle
ja,in dem du folgendes machst

Code:
while
{
  Aufruf();
  Thread.Sleep(TimeSpan.FromSeconds(5));
}

und bitte noch folgendes machen
Code:
empfaenger.Replace("'", "´");
bezüglich SQL Injection.
oder gleich richtig wie in meinem Letzten Post vorgeschlagen :)
 
Zurück
Oben