LocalStone
Messages postés514Date d'inscriptionmercredi 19 mars 2003StatutMembreDernière intervention 1 mars 2009
-
9 juin 2006 à 14:00
cs_coq
Messages postés6350Date d'inscriptionsamedi 1 juin 2002StatutMembreDernière intervention 2 août 2014
-
10 juin 2006 à 12:06
Bonjour,
Alors voilà ... Cette fois, ça y est, j'ai compris le mécanisme des events ... Alléluia comme dirait l'autre ... Bref. Du coup, je me retrouve avec une classe Server qui va posséder des evenements différents. Du coup, je suis obligé (je crois) de créer autant de classes que d'évenements différents ... Et du coup, est-ce qu'il est judicieux de placer l'ensemble des classes et des délégués comme internes à la classe ?
En gros, est-ce que ça, c'est bien (surtout la partie en rouge) ?
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace ConsoleApplication1
{
class Server
{
public event ServerEventHandler OnMessage;
// Client.
TcpClient Client;
// Port à écouter.
private int Port;
// TCPListener.
private TcpListener Listener;
// Thread du TCPListener.
private Thread ListenerThread;
// Constructeur.
public Server(int port)
{
this.Port = port;
this.ListenerThread = new Thread(this.Listen);
}
// Démarrage de l'écoute du serveur.
public void Start()
{
this.ListenerThread.Start();
}
// Ecoute du serveur.
private void Listen()
{
TcpClient client;
IPEndPoint ip;
this.Listener = new TcpListener(new IPEndPoint(IPAddress.Parse("127.0.0.1"), this.Port));
this.Listener.Start();
//this.Listener.
client = this.Listener.AcceptTcpClient();
this.Client = client;
ip = (IPEndPoint)client.Client.RemoteEndPoint;
//this.Send("Bienvenue " + ip + " !");
//Console.WriteLine(Convert.ToString(client.Connected));
this.Send("Salut à toi, " + ip.ToString() + " ... Soit le bienvenue. ");
Thread receive_thread = new Thread(new ThreadStart(this.Receive));
receive_thread.Start();
}
// Arrêt de l'écoute du serveur.
public void Stop()
{
//this.ListenerThread;
}
// Envoie d'un message.
public void Send(string text)
{
TcpClient client;
Stream stream;
BinaryWriter writer;
client = this.Client;
stream = client.GetStream();
writer = new BinaryWriter(stream);
writer.Write(text);
}
// Reçoit un message.
public void Receive()
{
TcpClient client;
Stream stream;
BinaryReader reader;
try
{
while (true)
{
text = Convert.ToString(Convert.ToChar(reader.ReadByte()));
ServerEventArgs e;
e = new ServerEventArgs(text);
if (this.OnMessage != null) this.OnMessage(this, e);
}
}
catch
{
}
finally
{
this.Client.Close();
}
}
internal class ServerEventArgs : EventArgs
{
private string _message;
public string Message
{
get
{
return _message;
}
}
Nikoui
Messages postés794Date d'inscriptionvendredi 24 septembre 2004StatutMembreDernière intervention19 août 200813 9 juin 2006 à 14:06
La réponse à la question m'interresse car je ne sais toujours pas non plus comment organiser ces classes (les "event args")...
Cela dis petite précision tu n'a pas forcément autant de classe / délégué que d'évènement, tu peux factoriser lorsque c'est possible :
Par exemple dans le Framework, les évènements Form.Load et Timer.Tick utilisent tous les deux un simple EventArgs. De la même façon, les évènement de souris utilisent généralement tous le même MouseEventArgs...
LocalStone
Messages postés514Date d'inscriptionmercredi 19 mars 2003StatutMembreDernière intervention 1 mars 2009 9 juin 2006 à 14:10
Bah en fait, ici, par exemple, il y a l'evenement OnMessage qui permet d'obtenir le message, mais y aura aussi l'evenement OnNewConnexion qui permetera d'obtenir l'IP de la personne qui veut se connecter, etc. ... Je ne pense pas que l'on puisse factoriser dans ce cas là.
Maintenant, c'est clair que si l'évenement n'a rien à retourner ... Bah la factorisation est possible.
Localstone
Nikoui
Messages postés794Date d'inscriptionvendredi 24 septembre 2004StatutMembreDernière intervention19 août 200813 9 juin 2006 à 14:16
Effectivement tu ne peux pas tout factoriser... mais par exemple si tu as un evènement OnNewConnexion tu aura surement aussi un évènement OnConnexionLost, ou bien encore OnDisconnexion... et tu pourrais dans ce cas utiliser le même "event args", qui contiendrait par exemple l'ip concernée + l'état de la connexion. Dans ce cas ça à un sens, mais effectivement, le OnMessage est différent et aura sa propre classe d'argument...
Ca permet en tout cas de réduire un peu le nombre de ces classes, car ca grossit vite, et tout comme toi je ne sais jamais trop comment "ranger" tout ça... (par contre attention à ne pas vouloir trop factoriser en regroupant des choses qui n'ont rien a voir, car la on sacrifie la clareté du code pour réduire son "volume" et c'est généralement pas une bonne idée ;)
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 9 juin 2006 à 14:59
Salut,
Si ton évènement est public ta classe *EventArgs et ton delegué *EventHandler ne doivent pas être "nested", imbriqués, bien que soit possible mais en tout cas il doivent avoir le même niveau de visibilité que l'évènement car si l'évènement est accessible et pas son paramètre par exemple,il y a un problème..
Pour un bon exemple d'implémentation du modèle des évènements regard ce code de Coq, qui est parfait et respecte le modèle avec les méthodes protégées On*...
LocalStone
Messages postés514Date d'inscriptionmercredi 19 mars 2003StatutMembreDernière intervention 1 mars 2009 10 juin 2006 à 12:00
Ok, je prends note de tout cela également. D'ailleurs, merci du "tuyau" pour EventHandler< TEventArgs >, ça rend le code plus propre et plus joli (je trouve ...) !
++ !
Localstone