\

Školení Návrhové vzory, OOP a UML


 Sunday, October 17, 2004
Dotazy a odpovědi k .NET Remotingu

Tento spot přímo navazuje na starší spot o nejčastějších problémech v .NET Remotingu.

Dotazy v konferencích se často týkají událostí. Důvodem je hlavně to, že mnoho knih (namátkou třeba Building XML Web Services for Microsoft .Net platform) obsahuje “postup” pro rozchození události, který nefunguje. V čem je problém?

Když ve vzdáleném serverovém objektu nadeklarujete událost a pokusíte se k ní zaregistrovat delegáta ukazujícího na metodu na klientovi, dostanete při běhu aplikace výjimku, že se nepodařilo nahrát assembly s typem, ve kterém se nachází klientská obslužná metoda události. Server odmítne registraci delegáta u události, protože nedokáže ověřit signaturu metodu, na níž odkazuje delegát - server nemůže nalézt assembly s typem, ve kterém je deklarována metoda, protože assembly je známa a rozmístěna jen na klientovi.

Správný postup při deklaraci a používání událostí v .NET Remotingu

  1. Vytvořte jednu assembly se serverovým objektem a nadeklarujte serverové události. Assembly umístěte pouze na serveru.
  2. Vytvořte assembly, v níž bude sdílená třída s obslužnou metodou serverové události a dále bude třída obsahovat událost vlastní, která bude stejného typu jako serverová. V těle obslužné metody serverové události pouze vyvolejte událost vlastní - lokální a přepošlete argumenty obdržené ze serveru. Assembly umístěte na server i na klienta, protože klient si zaregistruje obslužnou metodu sdíleného typu k serverové události (v té chvíli již server dokáže ověřit signaturu metodu a nahrát typ, ve kterém je metoda deklarována) a současně si klient přihlásí odběr lokální události ze sdíleného typu a takto zprostředkovaně zpracuje událost ze serveru.
  3. Vytvořte klientskou assembly. Assembly umístěte pouze na klienta.

Dalším problémem u vzdálených událostí je korektní ošetření stavu, kdy se klient odpojí a na serveru zůstane zaregistrován delegát (například spadne spojení). Aby nedošlo k výjimce na serveru při pokusu distribuovat událost, tak jako nejjednodušší cesta se nabízí dekorování obslužné metody na klientovi atributem OneWay - atribut způsobí, že server ignoruje všechny návratové hodnoty a výjimky z metody. Velkou nevýhodou je ale hromadění delegátů ukazujících do "prázdna" a tím zvýšená režie na distribuci každé události. Lepším řešením je ruční vyvolání každého delegáta registrovaného k události a po odchycení výjimky vyřazení delegáta z další distribuce událostí.

public void OnServerEvent(EventArgs e)
{
    Delegate[] delegatesList = ServerEvent.GetInvocationList();
    foreach(ServerEventHandler clientDelegate in delegatesList)
    {
        try
        {
            clientDelegate(e);
        }
        catch
        {
            ServerEvent -= clientDelegate;
        }
    }
}



Sunday, October 17, 2004 5:33:00 PM (Central Europe Standard Time, UTC+01:00)       
Comments [8]  .Net Remoting


Tuesday, July 19, 2005 11:01:28 AM (Central Europe Standard Time, UTC+01:00)
Dobry den
Clovece vy jste uzasnej :), zrovna tenhle problem jsem ted resil a nakonec vyresil stejnym zpusobem, skoda ze jste tenhle spot nenapsal driv... Jenom mam mensi problem pri pripojeni kazdeho dalsiho klienta k serveru, serverova udalost se ...
Tuesday, July 19, 2005 11:01:28 AM (Central Europe Standard Time, UTC+01:00)
:) Diky, jsem rad, ze to nekomu pomuze.
Kdyz se divam do vaseho kodu, vidim hned, ze misto udalosti pouzivate primo delegata-ale misto retezeni delegatu vzdy jen ukazujete na posledniho predaneho
DriverEvent = new ...
Tuesday, July 19, 2005 11:01:28 AM (Central Europe Standard Time, UTC+01:00)
No tak ted se trosku stydim :) samozrejme ted uz to funguje, omlouvam se za zneuziti diskuse pod spotem. ;)
Tuesday, July 19, 2005 11:01:28 AM (Central Europe Standard Time, UTC+01:00)
Ke stydeni neni duvod:) Selektivni slepota je nejhorsi - vzpominam si, jak jsem po delsi praci na projektu a po vyzkouseni vsech moznych kombinaci znechucene prohlasil, ze reflection Microsoftu opravdu nefunguje.
Kolega, ktery se prisel podivat na ...
Tuesday, July 19, 2005 11:01:28 AM (Central Europe Standard Time, UTC+01:00)
To Rene:> Tomu se rika "problem pres rameno". Uz se Vam nekdy stala tahle situace:

Dve hodiny se trapite s nejakym vice ci mene jednoduchym problemem. Kdyz uz melete s posledniho tak kriknete na sveho kolegu "Lojzo, muzes na ...
Tuesday, July 19, 2005 11:01:28 AM (Central Europe Standard Time, UTC+01:00)
To Petr: Mate pravdu, tuhle situaci presne znam taky a pojem "problem pres rameno" se mi hodne libi:)
Tuesday, July 19, 2005 1:22:55 PM (Central Europe Standard Time, UTC+01:00)
Test
Rene
Tuesday, November 28, 2006 2:22:32 PM (Central Europe Standard Time, UTC+01:00)
Zdravim,

aj ked tato diskusia prebehla uz davnejsie, skusim...
Suhlasim, ze pri nasilnom odpojeni klienta od servera pri atribute [OneWay] ostava stale klient odberatelom udalosti a server sa s tym sam nevie vysporiadat (ma neskutocnu reziu pri opakovanych pokusoch :-( ) a je preto treba takehoto klienta odhlasit z odberu udalosti na strane servera, toto riesenie aj predstavujete, ale...
Atribut [OneWay] zabezpecuje aj asynchronne volanie bez blokovania servera a ked ho odstranime, podla mna, je potrebne zabezpecit aby odber udalosti cez vrstvu remotingu bol asynchronny, co defaultne nie je. V opacnom pripade dochadza k blokovaniu servera. Suhlasite?

Dakujem
Milan
Comments are closed.