AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi [Indy 10] IRC-Client in eigenem thread auslagern
Thema durchsuchen
Ansicht
Themen-Optionen

[Indy 10] IRC-Client in eigenem thread auslagern

Ein Thema von Sfaizst · begonnen am 10. Dez 2010 · letzter Beitrag vom 22. Dez 2010
Antwort Antwort
Sfaizst

Registriert seit: 16. Jun 2008
33 Beiträge
 
#1

AW: [Indy 10] IRC-Client in eigenem thread auslagern

  Alt 22. Dez 2010, 04:23
Danke erstmal für die Tipps und die Info, gebracht hats aber scheinbar nicht viel, ich habe zudem mal probeweise die proceduren "onraw" und "onstatus" hinzugefügt, diese Funktionieren auch (man sollte zudem bemerken, wenn ich über IRC.Raw eine Naricht schicke wird diese gesendet (, kommt auch brav beim Server an) und wird bei "OnRaw" angezeigt, empfangen kann ich immernoch keine Narichten (Status, ping-pong,ect. geht, nur eben das wichtigste der chat selber eben nicht).

Momentane Source (ich war zu faul Form66 wieder in Form1 umzubenennen ):

Delphi-Quellcode:
unit Unit66;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IDIRC, IDContext, StdCtrls, IdBaseComponent, IdComponent;

type
  TForm66 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Button3: TButton;
    procedure FormDestroy(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

  type TIRC = class(TThread)
    private
      IRC : TIDIRC;
      FConnected : Boolean;
      FMessage : String;
      procedure OnPrivateMessage(ASender: TIdContext; const ANicknameFrom, AHost, ANicknameTo, AMessage: String);
      procedure OnStatus(ASender: TObject; const AStatus: TIdStatus;const AStatusText: string);
      procedure OnRaw(ASender: TIdContext; AIn: Boolean; const AMessage: String);
      procedure WriteMessageInMemo;
    public
      Host, Channel, Name : AnsiString;
      Port : Word;
      constructor Create(CreateSuspended:Boolean);
      procedure StartIRC;
      procedure SendText(Content : AnsiString);
      procedure Execute; override;
      destructor Free;
end;

var
  Form66: TForm66;
  AIRC : TIRC;

implementation

{$R *.dfm}

constructor TIRC.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  IRC := TIDIRC.Create(nil);
  IRC.OnPrivateMessage := OnPrivateMessage;
  IRC.OnStatus := OnStatus;
  IRC.OnRaw := OnRaw;
end;

procedure TIRC.StartIRC;
begin
  IRC.Host := Host;
  IRC.Port := Port;
  IRC.Username := Name;
  IRC.Realname := Name;
  IRC.Nickname := Name;
  IRC.Connect;
  IRC.Join(Channel);
  FConnected := True;
end;

procedure TIRC.Execute;
var
  ASender : TIDContext;
  ANick,AHost,ANickTo,AMessage : String;
begin
  while (not Self.Terminated) do
    begin
// if (FConnected) and (IRC.Connected) then
        Sleep(25);
    end;
    IRC.Disconnect('Ich hau ab!');
end;

destructor TIRC.Free;
begin
  try
  IRC.Free;
  except
  end;
  inherited Destroy;
end;

procedure TForm66.Button1Click(Sender: TObject);
begin
  Button1.Enabled := False;
  Button2.Enabled := True;
  AIRC := TIRC.Create(False);
  with AIRC do
    begin
      Host := '*****.ath.cx';
      Port := 6667;
      Channel := 'Testchannel';
      Name := 'Testuser';
      StartIRC;
    end;
end;

procedure TForm66.Button2Click(Sender: TObject);
begin
  Button2.Enabled := False;
  Button1.Enabled := True;
  AIRC.Terminate;
end;

procedure TForm66.Button3Click(Sender: TObject);
begin
if Edit1.Text <> 'then
  begin
    AIRC.SendText(Edit1.Text);
    Edit1.Text := '';
  end;
end;

procedure TForm66.FormDestroy(Sender: TObject);
begin
  if not AIRC.Terminated then
     AIRC.Terminate;
end;

procedure TIRC.SendText(Content: AnsiString);
begin
  IRC.Raw('PRIVMSG '+'#'+Channel+' :'+Content);
end;

procedure TIRC.OnStatus(ASender: TObject; const AStatus: TIdStatus;const AStatusText: string);
begin
  FMessage := AStatusText;
  Synchronize(WriteMessageInMemo);
end;

procedure TIRC.OnPrivateMessage(ASender: TIdContext; const ANicknameFrom: string; const AHost: string; const ANicknameTo: string; const AMessage: string);
begin
  FMessage := ANicknameFrom +': '+ AMessage;
  Synchronize(WriteMessageInMemo);
end;

procedure TIRC.OnRaw(ASender: TIdContext; AIn: Boolean; const AMessage: String);
begin
  FMessage := AMessage;
  Synchronize(WriteMessageInMemo);
end;

procedure TIRC.WriteMessageInMemo;
begin
  if FMessage <> 'then
    begin
      Form66.Memo1.Lines.Add(FMessage);
      FMessage := '';
    end;
end;

end.
So sieht die Memo aus, nach einem Connect und nachdem ich was gesendet und empfangen habe(n sollte):
Zitat:
Resolving hostname *****.ath.cx.
Connecting to **.**.***.**.
Connected.
NICK Testuser
USER Testuser 0 * :Testuser
NICK :Testuser
001 Testuser :Welcome to the My IRC Network Testuser!Testuser@........de
002 Testuser :Your host is ......, running aIRCServer
003 Testuser :This server was created Thu Jun 14 at 2001
004 Testuser ...... aIRCServer iswo opsitnmlbvk
005 Testuser ...:are available on this server
251 Testuser :There are 4 users and 1 services on 1 servers
252 Testuser 0 perator(s) online
253 Testuser 3 :unknown connection(s)
254 Testuser 3 :channels formed
255 Testuser :I have 4 clients, 1 services and 1 servers
422 Testuser :MOTD File is missing
PRIVMSG #62.141.39.44-10052 :Hallo //Habe ich gesendet!
//HIER FEHLT DIE NARICHT DIE EMPFANGEN WERDEN SOLLTE....
QUIT :Ich hau ab! //Disconnect Button
Disconnecting.
Disconnected.
Ich hoffe du kannst mir weiterhelfen, ich kenns hald von den guten alten Sockets, dass ich die im Execute von Windows "abholen" musste.. deswegen bin ich auch beim IRC davon ausgegeangen, wenn ich jedoch seh, dass eigentlich alles geht kanns das ja auch nicht sein (wie du sagtest, da kümmert sich irc selber drum...)

Vielen Dank schonmal

Geändert von Sfaizst (22. Dez 2010 um 04:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: [Indy 10] IRC-Client in eigenem thread auslagern

  Alt 22. Dez 2010, 08:47
Hi,

der Source sieht soweit eigentlich schon ganz gut aus,
wie gesagt ich kenne die Kompo "TIdIRC" noch nicht aus persönlicher Erfahrung,
deshalb kann ich keine fehlerhafte Implementierung der Indys ausschliessen,
das würde mich aber sehr wundern. Welche Version der Indys verwendest Du ?
denn aktuellen Branch aus dem SVN oder die mit Delphi ausgelieferte Version ?

Bekommst Du den das Event OnPrivateMessage, wenn Du die Komponente ohne Thread verwendest ?

Für Deinen Source habe ich eigentlich nur Änderungsvorschlag :
Delphi-Quellcode:
procedure TIRC.Execute;
var
  ASender : TIDContext;
  ANick,AHost,ANickTo,AMessage : String;
begin
  // ich würde den Thread suspended erzeugen, komplett connecten und erst danach den Thread starten/resumen
  // dann kann hier auch auf connected geprüft werden
  while (not Self.Terminated) and (IRC.Connected) do
    begin
// if (FConnected) and (IRC.Connected) then
        Sleep(25);
    end;
    IRC.Disconnect('Ich hau ab!');
end;
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.

Geändert von DataCool (22. Dez 2010 um 08:49 Uhr) Grund: Was vergessen
  Mit Zitat antworten Zitat
Sfaizst

Registriert seit: 16. Jun 2008
33 Beiträge
 
#3

AW: [Indy 10] IRC-Client in eigenem thread auslagern

  Alt 22. Dez 2010, 11:44
Hey,
wie von mir erwarted hat das suspended erzeugen und das aufrufen von Connect im Execute nichts gebracht...
Ich verwende die bei Delphi 2009 mitgelieferte Version (Datum:29.08.2008), die Komponente (und OnPricateMessage) funktioniert, wenn ich sie ohne Thread direkt zur laufzeit erzeuge...

Grüßle (ich schau mal nach der aktuellsten Indy Verison und melde mich dann wieder)
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: [Indy 10] IRC-Client in eigenem thread auslagern

  Alt 22. Dez 2010, 11:58
Hi,

versuch das mal Bei Google suchentidirc OnPrivateMessage,
bist nicht der erste der sich mit dem Thema beschäftigt

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Sfaizst

Registriert seit: 16. Jun 2008
33 Beiträge
 
#5

AW: [Indy 10] IRC-Client in eigenem thread auslagern

  Alt 22. Dez 2010, 14:22
Hi,
ich hab das Problem gefunden, ich habe wie auch in den Posts oben beim Send (IRC.Raw) eine # vor den channel gesetzt, diese habe ich aber beim connecten nicht angegeben, d.h. der client hat in den richtigen Channel geschickt, aber in dem falschen channel auf die antwort gewarted (sowas kann natürlich wieder nur mir passieren), jetzt wird immerhin "onraw" aufgerufen (on privatemessage lustigerweise immernoch nicht, das ist mir aber auch relativ wurscht, solang ich an den Inhalt komme (mir war der absender des inhaltes ja nie wichtig), ich denke mal, dasses beim onprivatemessage auch nur irgendne kleinigkeit ist).

Sowas simples hätte ich echt nicht erwarted (aber immerhin hab ich jetz meine Basics über Multithreading mal wieder aufgefrischt und zudem mal die Indys geupdated)

Vielen Dank

Grüßle
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz