MagicBuzz
Messages postés4Date d'inscriptiondimanche 18 juillet 2004StatutMembreDernière intervention19 novembre 2005
-
18 juil. 2004 à 13:00
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019
-
18 juil. 2004 à 19:00
Bonjour, je suis en train de développer un jeu de type MUD (faire une recherche dans www.mud-connect.com pour plus d'infos).
Le jeu tourne donc en tant que sevice Windows, et attends des connections telnet.
Au départ, avant d'intégrer la partie des sockets, j'ai recopié l'exemle du tutorial de MSDN à propos des threads (mes sessions telnet sont dans des threads afin de ne pas bloquer l'éxécution de la routine principale du service)
En créant un thread dans le OnStart() du service, puis en le stopant avec Abort() puis Join() dans le OnStop() ca fonctionnait très bien (de même avec OnPause() et OnResume())
Seulement, depuis que mon thread contient des appels à Socket, il refuse de mourrir, je suis obligé de shooter le service via le gestionnaire des tâches pour arrêter le service.
Ci-dessous mon code :
Service1.cs:
Code :
namespace MagicMUD
{
public class Service1 : System.ServiceProcess.ServiceBase
{
Thread oThread;
if (handler.Connected)
{
Session oSession = new Session(handler);
oThread = new Thread(new ThreadStart(oSession.Run));
oThread.Start();
}
else
{
EventLog.WriteEntry("MagicMUD", "Error. Client disconnected before session starts", EventLogEntryType.Error, 103);
return;
}
}
}
}
public class Session
{
private Socket handler;
public Session(Socket handler)
{
this.handler = handler;
}
~Session()
{
if (this.handler.Connected)
{
this.handler.Shutdown(SocketShutdown.Both);
this.handler.Close();
}
}
public void Run()
{
string dataRcp = null;
while (true)
{
while (true)
{
byte[] bytes = new byte[256];
int bytesRec = handler.Receive(bytes);
dataRcp += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (dataRcp.IndexOf("\n") > -1)
{
break;
}
}
EventLog.WriteEntry("MagicMUD", "J'ai reçu ça : " + dataRcp, EventLogEntryType.Information, 1001);
byte[] msg = Encoding.ASCII.GetBytes(dataRcp);
handler.Send(msg);
if (dataRcp.IndexOf("quit") == 0)
{
EventLog.WriteEntry("MagicMUD", "Arrêt de la connection", EventLogEntryType.Information, 1003);
break;
}
dataRcp = null;
}
if (this.handler.Connected)
{
this.handler.Shutdown(SocketShutdown.Both);
this.handler.Close();
}
}
}
}
PS: Deplus, dans mon thread "Server", je voudrais stocket mes "Session", mais un tableau ne me semble pas terrible, car il va vite y avoir des trous (quand un joueur se déconnecte) et il faudra redimensionner le tableau à chaque nouvelle connection...
Y'a pas un objet collection avec "Add()" et "Remove()" accessible avec foreach ?
Je pense que ça pourrait résoudre en partie mon problème parceque de toute façon, actuellement, dès que je crée un thread "Session", je perds sa référence, donc impossible de le tuer proprement.
Ceci dit, le service refuse de s'arrêter même si aucune session n'a démarré donc...
MrDogbert
Messages postés133Date d'inscriptionjeudi 26 octobre 2000StatutMembreDernière intervention20 juillet 20041 18 juil. 2004 à 13:47
1/ ici c est un forum pour VB. mais bon ...
2/ ta variable "dataRcp" j en aurai fait un StringBuilder plutot qu un String car cela est couteux d instancier sans arret des String (qui sont des chaines de caractères fixes contrairement au StringBuilder)
3/ pour les collection tu dois pouvoir créer ta collection typée en héritant de CollectionBase et tu dois pouvoir rajouter un Enumerator a ta collection pour y accéder par un for each. Si tu hérites de CollectionBase regarde si mybase.list n en possède pas déjà un.
4/ j aurais fait la création des nouveaux thread dans le constructeur des classes Server ou Session ou dans la fonction startServer ou startSession plutot que dans la fonction qui instancie ces classes.
5/ pendant l execution d un thread tu peux faire thread.currentThread pour connaitre le thread qui exécute le code que tu regardes.
6/ Si tu créés le Thread dans la fonction sessionStart par exemple tu peux stocker le thread dans une variable globale de ton application.
7/ lors de l'appel a sessionStop tu peux essayer de faire thread.currentThread.stop par exemple.
8/ ta variable "oServer" dans "Service1" fais en une globale et appelle sa fonction stop() dans OnStop de ton service. tu auras la main sur le thread et sur l objet. là on ne sait pas vraiment ce que devient ton objet. il n est pas forcément détruit ce qui fait qu il n'appellera pas la destruction de tes sessions.
voila. pioches dans ces idées. ce n est pas la sainte bible mais ya petetre quelque chose de pas trop bete dedans.
BruNews
Messages postés21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 18 juil. 2004 à 19:00
Salut,
aucun probleme, manque seulement 'fr':
csharpfr.com
J'ai fait une csbar pour naviguer entre les differents sites CS, voir rubrique telechargements a gauche.