witam
Od jakiegoś czasu w wolnych chwilach pisze sobie bibliotekę do obsługi Gadu-Gadu, dzisiaj wydałem pierwszą wersję, jeżeli ktoś jest zainteresowany to zapraszam na:
http://dotgadu.sourceforge.net/
witam
Od jakiegoś czasu w wolnych chwilach pisze sobie bibliotekę do obsługi Gadu-Gadu, dzisiaj wydałem pierwszą wersję, jeżeli ktoś jest zainteresowany to zapraszam na:
http://dotgadu.sourceforge.net/
Niezłe - ja też na czymś takim pracuje : zobacz http://www.hakger.xorg.pl --> Sharp HGG. Na razie zrobiłem:
propozycja: może "złączymy siły" i będziemy wspierać jeden projekt?
propozycja wspierania jednego projektu wydaje sie calkowicie sensowna i na pewno przynioslaby lepsze rezultaty niz rozwijanie dwoch projektow osobno, ale widze ze twoja biblioteka jest w bardziej zaawansowanym stadium rozwoju niz moja, a wiec polaczenie sil prawdopodobnie musialoby oznaczac porzucenie DotGadu na rzecz Sharp HGG, a niestety chcialbym zrobic wlasna biblioteke, glownie ze wzgledow edukacyjnych ;-)
No to postanowiłem sprawdzić jak działa ta biblioteka ;) no i napotkałem dziwny problem.
Jeśli zostanie wywołana metoda przez delegacje np. „public void packet(IGaduPacket packet)” a w niej modyfikuje zawartość kontrolki:
" cmbStatus.Items.Add("Wysłano");
cmbStatus.Text = "Wysłano";"
wywala mi wyjatek… a jeśli to usune i umieszcze np MessageBox-a jest wsystko ok. Dlaczego???
private void btnZaloguj_Click(object sender, EventArgs e)
{
int nrGG = Int32.Parse(txtNrGG.Text);
GaduServer gaduServer = new GaduServer(nrGG);
cmbStatus.Items.Add("Łaczy z serverem");
cmbStatus.Text = "Łaczy z serverem";
gadu = new Gadu();
gadu.Reciever.OnLoginOK += new OnLoginOKHandler(loginok);
gadu.Reciever.OnLoginFailed += new OnLoginFailedHandler(loginfailed);
gadu.Reciever.OnLoginNeedEmail += new OnLoginNeedEmailHandler(loginneedemail);
gadu.Sender.OnPacketSended += new OnPacketSendedHandler(packet);
gadu.Connect(gaduServer);
cmbStatus.Items.Add("Połączono z serverem");
cmbStatus.Text = "Połączono z serverem";
gadu.Login(nrGG, mtbHaslo.Text);
}
private void btnWyloguj_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(5000);
gadu.Logout();
gadu.Disconnect();
cmbStatus.Items.Add("Rozłączono");
cmbStatus.Text = "Rozłączono";
}
public void packet(IGaduPacket packet)
{
cmbStatus.Items.Add("Wysłano");
cmbStatus.Text = "Wysłano";
}
public void loginok()
{
cmbStatus.Items.Add("Zalogowano");
cmbStatus.Text = "Zalogowano";
}
public void loginfailed()
{
cmbStatus.Items.Add("Błąd logowania");
cmbStatus.Text = "Błąd logowania";
}
public void loginneedemail()
{
cmbStatus.Items.Add("Mail");
cmbStatus.Text = "Mail";
}
szkoda ze nie napisales jaki jest to wyjatek, ale domyslam sie ze jest to
InvalidOperationException
jest to zwiazane z tym ze w GaduReciever dziala watek, ktory odbiera wszystkie pakiety, kazda delegacja wiec dziala w tym watku, co za tym idzie kiedy w event podstawisz kod modyfikujacy jakas kontrolke, jest ona modyfikowana z watku powolowanego przez GaduReciever, a nie z glownego watku apliacji, pczytaj o:
"How to make cross-thread calls to Windows.Forms Controls"
ew. mozesz pojsc na latwizne i w konstruktorze klasy, ktora jest okienkiem wpisz linike:
CheckForIllegalCrossThreadCalls = false;
problem powinien zniknac, ale polecam polecac poczytac o tym w jakis sposob bezpiecznie modyfikowac Windows.Forms z innych watkow niz glowny
poczytac o tym temacie mozna np. tutaj:
http://msdn2.microsoft.com/pl-pl/library/ms171728(en-us,VS.80).aspx
czester21 : podpowiedź: w shgg nie ma takiego wyjątku ;-) - zobacz funkcję PostCallback(). To programista klasy / biblioteki powinien o to zadbać, w końcu wyjątek leci z niej.
Hmmmm racja racja czas przysiąść się i poczytać o wielowątkowości ;) w książce Stephen-a C. Perry pt: „C# i .NET” autor pisze „Tworząc formularze Windows i ogólnie interfejsy użytkownika, trzeba pamiętać, że wszystkie kontroli formularza działają w tym samym wątku i należy w nich korzystać tylko z kodu tego wątku. Jeśli działa wiele wątków, danej kontrolki nie należy używać (nawet jeśli jest to techniczne możliwe) w żadnym kodzie oprócz kodu w wątku tej kontrolki. Jest to jedno z przykazań platformy .NET.
Wiec pozwolę sobie trochę pójść na łatwiznę zadać pytanie co mam zrobić żeby zmodyfikować kontrolkę z wątku kontrolek?? Czyli jak wnioskuje z wypowiedzi czester21 z wątku głównego tak?
najprosciej zrobic sobie delegacje, tutaj przyklad:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public delegate void setText(String text);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread thread=new Thread(new ThreadStart(thread_func));
thread.Start();
}
private void thread_func()
{
setText settext = new setText(setText_safe);
this.Invoke(settext, "abc");
}
private void setText_safe(String text)
{
textBox1.Text = text;
}
}
}
W przykladzie po kliknieciu na przysik zostaje utworzony watek, ktory wykonuje funkcje thread_func(), funkcja thread_func() nie zmienia jednak bezposrednio wartosci lineEdit1 aby nie wywolac bledu, robi to przez delegacje, kluczowym wlasciwie w tym przykladzie jest this.Invoke(), bo to dzieki temu delegacja wykona sie w watku okienka
Dzieki. Jak bede miał troche czasu to sprawdze i zabiore się z wielowątkowośc bo mam braki. Wkleje jeszcze co debuger wywala, może pomoże w udoskonaleniu biblioteki ;) bo jak Deti napisał nie powinien wyjątek wywalać.
DotGadu.GaduSenderException was unhandled
Message="Cross-thread operation not valid: Control 'cmbStatus' accessed from a thread other than the thread it was created on."
Source="DotGadu"
StackTrace:
at DotGadu.GaduSender.go() in C:\Documents and Settings\czester21\Pulpit\DotGadu\DotGadu\GaduSender.cs:line 149
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
czester21 napisał(a)
najprosciej zrobic sobie delegacje, tutaj przyklad:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public delegate void setText(String text);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread thread=new Thread(new ThreadStart(thread_func));
thread.Start();
}
private void thread_func()
{
setText settext = new setText(setText_safe);
this.Invoke(settext, "abc");
}
private void setText_safe(String text)
{
textBox1.Text = text;
}
}
}
W przykladzie po kliknieciu na przysik zostaje utworzony watek, ktory wykonuje funkcje thread_func(), funkcja thread_func() nie zmienia jednak bezposrednio wartosci lineEdit1 aby nie wywolac bledu, robi to przez delegacje, kluczowym wlasciwie w tym przykladzie jest this.Invoke(), bo to dzieki temu delegacja wykona sie w watku okienka
Można też
private void button1_Click(object sender, EventArgs e)
{
if (InvokeRequired) {
BeginInvoke(new EventHandler(button1_Click), sender, e);
return;
}
//kod obslugi eventu
}
dzisiaj wypuscilem nowa wersje DotGadu, zapraszam na:
http://dotgadu.sourceforge.net/
Gratulacje dla obu autorów za dobrą prace :) Mam tylko małe pytanie dla czestera21 - kiedy można się spodziewać obsługi polskich czcionek ;)?
Drakon napisał(a)
Gratulacje dla obu autorów za dobrą prace :) Mam tylko małe pytanie dla czestera21 - kiedy można się spodziewać obsługi polskich czcionek ;)?
ups.... zapomnialem ze w Gadu-Gadu wszystko lala w cp1250... poprawiony kod DotGadu juz na svn, w najblizszym czasie sprobuje znalezc troche czasu zeby sprawdzic czy dziala wszystko rowniez na MONO, jezeli bedzie ok to zbuduje paczki i wydam nowa wersje
oprocz wysylania/odbierania wiadomosci poprawilem rowniez zmiany statusow, tam tez zapomnialem o cp1250
dzisiaj znalazlem troche czasu na wypuszczenie nowej wersji :)
zapraszam na http://dotgadu.sf.net/
dzisiaj pojawiła się nowa wersja DotGadu, zapraszam:
http://dotnet.wsiz.rzeszow.pl/DotGadu/
http://dotgadu.sourceforge.net/index2.htm
http://dotgadu.sourceforge.net/
A słyszeliście o konkursie na projekt Open Source w .NET? :)
Może trochę więcej szczegółów .. kto, jak, gdzie, kiedy..
Witam i gratuluję twórcom świetnego pomysłu.
Mam jednak pytanie co do funkcjonowania jednej z funkcji. Chodzi mianowicie o tzw. "kontynuację" zapytań do katalogu publicznego. Chciałem dla przećwiczenia próbę stworzyć na bazie biblioteki dotgadu własną wyszukiwarkę kontaktów... i poza jednym małym problemem wszystko działa OK. Tym problemem jest parametr "FmStart" (numer, od którego rozpocząć wyszukiwanie, ma znaczenie, gdy kontynuujemy wyszukiwanie - do katalogu publicznego). Wygląda na to że system nie uwzględnia tego parametru w zapytaniach (tzn. niezależnie od tego jaką wartość FmStart podam zawsze dostają takie same wyniki).
Podaję przykładowy kod:
// --------------------------------------------------------------------------------------------------------
class Test
{
private Gadu m_gadu = null;
private int m_searchStart = 0; // Poczatkowa wartosc parametru FmStart.
private int m_count = 10; // Ile razy kontynuowac zapytanie.
public Test()
{
GaduServer gaduServer = new GaduServer("91.197.13.26" , 8074);
m_gadu = new Gadu();
m_gadu.Reciever.OnPubDirReplay += new OnPubDirReplayHandler(PubDirReplay);
m_gadu.Connect(gaduServer);
m_gadu.Login(1111 , "****"); // Wlasne parametry polaczenia do serwera gg :)
}
public void Search()
{
GaduUser gaduUser = new GaduUser();
gaduUser.Name = "Jacek";
gaduUser.FmStart = m_searchStart;
Console.WriteLine(m_count + ". Search from: " + m_searchStart);
m_gadu.PubDir.Search(gaduUser);
}
private void PubDirReplay(GaduPacketPubDir50 gaduPacketPubDirReplay50)
{
List<GaduUser> list = GaduUser.ParsePubDirString(gaduPacketPubDirReplay50.Data);
for (int i = 0 ; i < list.Count ; i++)
{
GaduUser user = list[i];
Console.WriteLine(user.Uin + " , " + user.Name + " , " + user.Nick);
m_searchStart = Math.Max(user.Uin + 1 , m_searchStart);
}
if (--m_count > 0)
{
Search(); // Kontynuacja zapytania.
}
else
{
m_gadu.Logout();
m_gadu.Disconnect();
}
}
private static void Main(string[] args)
{
Test test = new Test();
test.Search();
}
}
// --------------------------------------------------------------------------------------------------------
Za każdym razem (przy każdej kontynuacji) dostaję identyczne wyniki. Ponadto zwracane są kontakty z numerami gg niższymi niż zadany parametr FmStart (np. przy pierwszej kontynuacji parametr FmStart jest ustawiany na 10645484 a w wynikach jest kontakt o numerze 516284, tak jakby parametr FmStart w ogóle nie był uwzględniany. Wiem, że coś muszę robić nie tak jak trzeba, bo przecież w standardowym komunikatorze funkcja kontynuacji działa prawidłowo.
Chyba znalazłem rozwiązanie.
Parametr FmStart nie jest odpowiednikiem numeru gg!
Po wykonaniu zapytania do katalogu publicznego serwer zwraca serię wyników. Ostatni wiersz zawiera dane z zerowymi wartościami (numer gg = 0) oraz pewną liczbę w parametrze o nazwie "nextstart". Właśnie tę wartość trzeba pobrać z ostatniego wiersza wynikowego i przekazać ją do parametru FmStart w kolejnym zapytaniu.
Przy takim podejściu kontynuacja działa, ale też nie do końca tak jakby się można spodziewać. Otóż po (mniej więcej) 10 kontynuacjach ostatni wiersz wyniku zwraca "nextstart" = 0, więc dalsza kontynuacja jest niemożliwa. Tak jakby wyszukiwać można było tylko w jakimś początkowym zakresie numerów (mniej więcej do numeru gg 100000). Wygląda mi to na jakieś zabezpieczenie po stronie serwera gg - podobno robiono modyfikacje pod kątem bezpieczeństwa.
Witam.
A jak uruchomić program w sytuacji, gdy połączenie jest wykonane za pośrednictwem proxy ?
Klient SHGG ma o tyle wadę, że korzysta z metody RawSerialize, a do wielu stringów używa MarshalAs z właściwością ConstSize, której przypisuje się straszliwie wysoką wartość (1900+) bajtów.
Zatem każdy pakiet np. wiadomości do kogoś zajmuje wiecej niz 2kb, to czasami jest niedopuszczalne w szybkich transmisjach.
Pozdrawiam.
Jak kolega powyżej szukam rozwiązania jednak nigdzie go nie widać. Jak rozwiązać sprawę proxy? Obie biblioteki nie mają wsparcia - muszę podać IP,port,login i hasło aby dostać się do serwera.
Czy ktoś rozwiązał ten problem ?
To mój pierwszy post, więc witam wszystkich ;-)
Podjąłem się napisania własnego, prostego komunikatora na .NET. Chętnie wykorzystam jedną z Waszych bibliotek (skoro są open-source), jednak jak widzę zostały one wydane jakiś czas temu. Aby nie wynajdywać od nowa koła... czy ktoś ma może aktualniejszą wersję którejś z tych bibliotek? Od tamtego czasu na pewno nieco się w samym protokole gg zmieniło.
Oczywiście jeśli nikt tego nie ma to pozostanie mi aktualizacja na podstawie libgadu, ale może ktoś już jest nieco dalej?
podpowie ktoś jak używać tej biblioteki w VB.NET ?? bo po opisach z pliku pdf, nie mogę sobie poradzić, z użyciem biblioteki
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.