Witam, od wczoraj zacząłem pracę jako C# developer. Akurat tak się złożyło, że kolega co był odpowiedzialny za aplikacje wczoraj jak jechał do pracy miał wypadek samochodowy i leży w stanie krytycznym w szpitalu. Co stawia mnie w fakcie dokonanym iż szybko muszę się wdrożyć w program i poprawić błędy.
To co wyczytałem z dokumentacji do teraz, to troszkę rozumiem na czym się to kręci. Lecz nie w 100% procentach i obecnie bawię się w szukanie problemu gdzie może on występować.
Nakreślenie działania aplikacji
Technologia MDI // też do końca nie rozumiem jednego zjawiska jakie występuje
Network.JSON
Aplikacja tworzy sobie lisnera. Pobiera dane z nasłuchiwania localhost:60020.
Jej zadaniem jest pobranie pewnych zdanych z serwera, na którym znajduje się cała logika jakie elementy są przesyłane. Aplikacja je tylko wyświetla name i value podane jest to w JSON deserializacja działa classy są odpowiednio porobione.
Elementem który się psuje jest komunikacja z Wtyczką API stworzoną przez inny dział. Działanie wtyczki polega na zadaniu, wysłania komunikatu do programu o przesłanie jej elementów z PROGRAMU DO API. I tutaj się zaczyna cały problem.
Ponieważ raz działa, a czasem w logach API jest komunikat o timeower czyli nie otrzymała odpowiedzi zwrotnej.
I teraz jest tutaj moje zadanie, co jest grane. Z tego co wiem osoba, która to napisała ponoć 2 tygodnie się z tym męczyła.
Mniej więcej co muszę zrozumieć
private static HttpListener _listener = new HttpListener(); // stworzenie lisnera
_listener.Prefixes.Add("http://localhost:60020/"); // ustawienie nasłuchiwania
_listener.Start();
_listener.BeginGetContext(ProcessRequest, null); // odbieranie danych + wysyłka
To jest mniej więcej jak działa lisner.
I teraz mnie zastanawia fakt
_listner.Stop();
Jest to zatrzymanie nasłuchiwania. Nie zamknięcie, więc problem może się kryć tutaj iż się coś zwiesi albo proces się przeciąży.
więc ja bym użył Close(); przy zamknięciu formy(MDIParenta).
Jednak przy Close() jak 2 raz zamknę okno i otworze na nowo występuje mi problem przy _listener.Prefixes.Add
Tak wygląda cod zamknięcia okna. Jeżeli _listner.Stop(); będzie działać. W przypadku _listner.Close(); Za 2 otwarciem wystąpi problem
private void Open_first_form()
{
Hide();
Form1 categoryView = new Form1();
categoryView.MdiParent = MdiParent;
categoryView.Show();
this.Close();
}
A tak wygląda ProcessRequest
teraz mam mało czasu żeby to bardziej opisać co jest co. Obecnie czekam na wystąpienie problemu oraz informacje zwrotną na temat czy wtyczka z przeglądarki wysłała zapytanie do aplikacji.
Jak dojdzie zapytanie powinien stworzyć się log i będę wiedział wtedy że nie wysyła odpowiedzi czyli wina po stronie programu.
Jak nie dojdzie log to znaczy że jest problem w komunikacji wtyczki a aplikacji.
Tak mniej więcej to wygląda.
private void ProcessRequest(IAsyncResult result)
{
try
{
HttpListenerContext context = _listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
//Answer getCommand/get post data/do whatever
string postData;
// oczekiwanie na request od wtyczki
using (var reader = new StreamReader(request.InputStream, request.ContentEncoding))
{
//odczytanie wiadomosci od wtyczki
postData = reader.ReadToEnd();
Variables.write_to_log_file("[EXTENSION][Action] Receive : " + postData.ToString());
}
// sprawdzanie czy uzytkownik kliknal "WYPELNIJ" czy "ERROR"
if (postData.IndexOf("messageFromUser") != -1)
{
var errorInfo = JsonConvert.DeserializeObject<ErrorMessageObject>(postData);
ErrorMessage form = new ErrorMessage();
form.ShowDialog();
// Odpowiedz
string responseString = "response";
HttpListenerResponse response = context.Response;
response.ContentType = "text/html";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
_listener.BeginGetContext(new AsyncCallback(ProcessRequest), null);
// Wyslanie info do API
IDictionary<string, string> parametry = new Dictionary<string, string>();
parametry["klasyfikator1"] = errorInfo.url;
parametry["klasyfikator2"] = errorInfo.title;
parametry["klasyfikator3"] = errorInfo.desc;
parametry["info"] = Variables.msg;
string responseFromAPI = Variables.User.api_command(parametry, "patternDontWork");
var responseFromApiObject = JsonConvert.DeserializeObject<ErrorMessageResult>(responseFromAPI);
MessageBox.Show(responseFromApiObject.message, "Status: " + responseFromApiObject.status);
}
else
{
// deserializacja
var CartInfo = JsonConvert.DeserializeObject<RootObject>(postData);
// pobranie configa wzorcow
var configWzorceString = new WebClient().DownloadString(Variables.apiLink + "/files/config/configWzorce.json");
// deserializacja
var configWzorceJson = JsonConvert.DeserializeObject<RootArr>(configWzorceString);
RootObject objectToSend = new RootObject();
foreach (var objectFromExtension in CartInfo.arr)
{
foreach (var objectFromConfig in configWzorceJson.arr)
{
if ((objectFromExtension.title == objectFromConfig.klasyfikator2) &&
(objectFromExtension.url == objectFromConfig.klasyfikator1) &&
(objectFromExtension.desc == objectFromConfig.klasyfikator3))
{
foreach (var value in objectFromConfig.data)
{
foreach (var dataPerson in Dane.Where(dataPerson => value.bazaItem == dataPerson.Key))
{
value.bazaValue = dataPerson.Value;
}
if (value.bazaItem == "wojewodztwo")
{
value.bazaValue = wojewodztwo;
}
if (value.bazaItem == "urodzenie_data")
{
value.bazaValue = birth;
}
}
objectToSend.arr.Add(new Arr()
{
arrayDataInfo = objectFromConfig.data,
index = objectFromExtension.index
});
}
}
}
string responseJSON = JsonConvert.SerializeObject(objectToSend, Formatting.Indented,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
// RESPONSE
string responseString = responseJSON;
HttpListenerResponse response = context.Response;
response.ContentType = "text/html";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
_listener.BeginGetContext(new AsyncCallback(ProcessRequest), null);
}
}
catch { }
}
}
I zastanawia mnie ten fragment
_listener.BeginGetContext(new AsyncCallback(ProcessRequest), null);
Co konkretnie się w tym momencie wykonuje.
Z dokumentacji jaką znalazłem z przykładami powinno się znajdować _listener.Stop();
Był bym wdzięczny za wytłumaczenie. I teraz jak tak to oglądacie to problem waszym zdaniem jest pomiędzy.
Wtyczka -> Program
Program -> Wtyczka
W samym programie
Czy może po stronie jeszcze serwera API, a może jeszcze gdzieś indziej