13 Comments
ssh shell vps ubuntu

Svaki pravi web developer bi sigurno htio imati jedan web server! Cijeli server, sa pristupom cijelom operativnom sustavu, da si moze naštimavati sve opcije, optimizirati, podešavati i tjunirati svaki HTTP paket koji odlazi. Kod shared hosting paketa se dobije samo FTP pristup i osnovna funkcionalnost putem nekog Control Panela, ali dalje od tih opcija se ne može. Nista od štimanja ISAPI filtera, mapiranja ekstenzija, dodavanja neograničeno domena i slicnih stvarčica. Za takve stvari ipak treba imati telnet, ssh ili remote desktop pristup, i dozvole podešavanja. To imaju Dedicated i VPS server, od kojih je ovaj prvi pre skup (cca od 50$/mj) i odmah ću ga odbaciti, ali ovaj drugi, VPS server, se ipak može pronaći za skromnije novce. Cijena uglavnom ovisi o dostupnom RAMu i procesorskoj snazi.

Pošto se ovdje radi o pokretanju .NET web aplikacija, u obzir prirodno dolaze samo Windows serveri, ali zahvaljujući Novellu i Miguel de Icazi, aplilacije možemo pokretati i na Linuxu uz pomnoć Mono projekta.

Ako spojimo VPS Linux hosting i Mono framework, znači da već za 9,99$ mjesečno imamo svoj vlastiti server s kojim možemo raditi što god nas je volja! Već neko vrijeme planiram zakupiti jedan takav VPS server i poigrati se. Neki da sam konačno našao vremena, volje, i 10$ viška i zakupio mjesec dana VPSa na jednom od hosting providera. Kroz par postova ću probati opisati postupak konfiguriranja servera, u cilju pokretanja ASP.NET stranica, točnije ovog bloga, i za moje privatne (fuš) potrebe, N2CMSa. Još nisam siguran dali će N2CMS raditi, ali BlogEngine.NET provjereno radi na Mono frameworku.[more]

Krenimo redom; prvo je potrebno izabrati hosting providera sa VPS uslugom. Neki koje sam ja pronašao guglajući su: Fsckvps, IntoVPS, EnjojVPS. Sve su to UNMANAGED serveri, što znači da se dobije ssh pristup, i to je to, snalazi se sam. Uvijek sam mislio da to uključuje kompajliranje kernela i piskaranje gomila konfiguracijskih fajlova, ali nije tako; kernel dođe kompajliran, a konfiguracijske skripte se moraju samo malo piskarati ;) Znači čaša je na pola puna, a ne prazna!

Kada se zakupi VPS, dobije se SSH pristup shellu, kojem pristupamo pomoći nekog ssh/telnet programa poput PuTTy.  Također, gotovo svi hosting provideri daju mogučnost odabira Linux distribucije, i ja sam za ovu priliku izabrao Ubuntu (iako sam prvo uzeo SuSE, pošto je njegov proizvođač Novell, a on je napravio i Mono, ali na njemu mi ništa nije htjelo proraditi, pa sam se prebacio na Ubuntu). Većina providera ima Ubuntu 9.04 Jaunty.

Nakon što smo se spojili na naš novi server, ostaje nam za napraviti sljedeće:

  1. refreshati repozitorije: na Linuxima postoji pojam paketa i repozotorija. To je centralizirano mjesto za instalaciju aplikacija. Takvog čega nema na Windowsima, a radi se o spisku dostupnih aplikacija (paketa) koji je sadržan u jednom ili više repozitora. Korisnik samo mora odabrati željenu aplikaciju (paket), a aplikacijski instalacijski program (apt-get, zypper, yast, …) će ju instalirati, uključujući zavisne biblioteke i programe (nešto tipa DLLova)
    Naredba za update repozitorija: apt-get update
    Naredba za instalaciju aplikacija: apt-get install NazivAplikacije
    Pregled liste dostupnih aplikacija: apt-cache search [NazivApp*]
  2. pošto nisam vičan radu u Bashu preko SSH (ala command prompt na win), ja sam instalirao i sljedeće: Gnome desktop grafično sučelje, VNC server za pristup (ala Remote Desktop)
    Cijeli postupak je objašnjen ovdje, i meni osobno je prošao bez ikakvih problema:
    http://markus.revti.com/2009/08/installing-vnc-remote-desktop-on-ubuntu-linux-vps/
    uz jednu napomenu; ubuntu dolazi sa VI editorom (ala DOSov Edit, ili Win Notepad), koji je meni jako zbunjujuć za raditi, pa sam ja instalirao Nano editor:
    sudo apt-get install nano (ovaj sudo označava pokretanje programa sa root pravima)
  3. instalacija Mono frameworka
  4. instalacija Apache web poslužitelja
  5. instalacija XSP (mono web server, služi Apachu za izvršavanje ASP.NET aplikacija). Konfiguracija mod_mono, da Apache koristi XSP za ASP.NET
  6. testitranje sa više domena i poddomena, N2CMS, BlogEngine.net,…
  7. instaliranje i podešavanje Firewalla

Za sada sam došao do koraka 3, a daljnji napredak ću opisati u sljedećim postovima. Trenutno imam remote desktop pristup serveru, i u instalacijom programu Gnomea (izbornik System/Administration/Synaptic Package Manager)  se nalazi Mono framework 2.0. Zadnja verzija Mono frameworka je 2.4 (podržava C# 3.0, MVC, bez LINQ2SQL), i potrebno je dodati ovaj repozitorij:
deb http://ppa.launchpad.net/directhex/monoxide/ubuntu jaunty main (u Synapticu, izbornik Settings/Repositories/Third party sw). Time smo dobili mogučnost instalacije Mono 2.4 frameworka. Putem Synaptica možemo instalirati i Monodevelop, IDE alat za razvoj .NET aplikacija.

Jedna sitnica, ako vam layout tastature ne štima, odnosno pritisnete D a on ispiše F, onda pogledajte ove upute: https://bugs.launchpad.net/ubuntu/+source/vino/+bug/112955/comments/55

Nastavak slijedi brzo…

0 Comments
Mediator

U izradi Silverlight (ili WPF, WinForms…) aplikacija, često se javlja potreba za komunikacijom različitih dijelova aplikacije, poput različitih User Control-a, instanciranih objekata i slično. Najbolje da jednim primjerom objasnim problematiku: za izradu Silverlight aplikacije za praćenje riječkog karnevala (izrađeno 2008., nadam se da je još online!) morao sam implementirati "pametno" sučelje, koje ispisuje informacije o trenutnoj skupini koja prolazi, označiti ju na listi, i još par sitnica. Te informacije sam dobivao preko web servisa u lokalni "provider" podataka, i pomoću evenata/delegata u kodu se predplaćivao na taj "providera" i slao potrebne objekte svim pretplatnicima na evente. Kako se sučelje sastoji od dosta user controla i custom controla, orkestracija pretplate prilikom starta aplikacije odnosno kreiranja objekata je bila relativno kompleksna. Na kraju izrade bilo mi je jasno da to i nije nabolje rješenje i da mora postojati jednostavniji način. Nedugo potom sam naišao na jedan design pattern, za koji sam znao da postoji ali ga nikada nisam imao priliku iskoristiti, pretpostavljam zbog samom načina rada web aplikacija. Radi se o Mediator patternu, koji definira komunikaciju između objekata.

Mediator UML sequenceJedan od mojih prethodnih blog postova objašnjava izradu ViewModela, prema Model-View-ViewModel patternu. Mediator pattern se savršeno uklapa u naš ViewModel, stoga ćemo iskoristiti MVVM i dodati potrebne klase. 
U svojoj osnovi, stvar ovako funkcionira: objekti se pretplate (Subscribe(tip poruke)) na određene poruke Mediator objektu (MessageGateway u primjeru). Ti objekti mogu i poslati poruku (Publish(ChatMessage)) Mediator objektu, koji potom prosljeđuje poruku svim pretplatnicima koji su se pretplatili na taj tip poruke (ReceiveMessage(poruka)).[more]
Naša mediator klasa:

public class MessageGateway
{
    private static MessageGateway gateway;

    /// <summary>
    /// Singleton instanca MessageGateway objekta
    /// </summary>
    /// <value>Statična MessageGateway instanca</value>
    public static MessageGateway Instance
    {
        get
        {
            if(gateway==null)
                gateway=new MessageGateway();
            return gateway;
        }
    }

    /// <summary>
    /// Lista pretplatnika na tipove poruka; svaki tip poruke moze imati vise pretplatnika
    /// </summary>
    private Dictionary<Type,List<WeakReference>> subscribers;

    /// <summary>
    /// Pretplata na specifičnu poruku
    /// </summary>
    /// <param name="receiver" />Pretplatnik</param>
    /// <param name="message" />Tip poruke</param>
    public void Subscribe(IReceiver receiver,Type messageType)
    {
        if(messageType!=typeof(MessageBase) && !messageType.IsSubclassOf(typeof(MessageBase)))
            throw new ArgumentException("Parametar mora biti tipa MessageBase","messageType");

        if(subscribers==null)
            subscribers=new Dictionary<Type,List<WeakReference>>();

        if(!subscribers.ContainsKey(messageType))
            subscribers.Add(messageType, new List<weakreference>());  
         
        subscribers[messageType].Add(new WeakReference(receiver));
    }

    /// <summary>
    /// Objava poruke svim pretplatnicima
    /// </summary>
    /// <param name="message" />Poruka</param>
    public void Publish(MessageBase message)
    {
        if (subscribers == null) return;
        
        foreach(Type type in subscribers.Keys)
        {
            if(message.GetType() == type || message.GetType().IsSubclassOf(type))
            {
                foreach (var reference in subscribers[type])
                {
                    if (reference.IsAlive && reference.Target != null)
                        ((IReceiver)reference.Target).ReceiveMessage(message);
                }
            }
        }
    }
}
WeakReference: tip reference na objekt, koja dopušta Garbage Collectoru da uništi objekt iako je referenciran ovim tipom reference. Sa IsAlive provjeravamo dali referencirani objekt postoji
Dvije su glavne metoda u ovoj klasi: Subscribe i Publish. Objašnjenje:
Subscribe: svaki objekt koji se želi pretplatiti na poruke mora implementirati IReceiver interface. On mu omogućava primanje poruka. Metoda interno koristi Dictionary, gdje je za svaki ključ (Type, tip poruke), vezana lista pretplatnika. Ako ključ ne postoji, on se dodaje u Dictionary, kreira nova lista, i na kraju dodaje referenca (WeakReference) pretplatnika.
Publish: u Dictionaryu pretplatnika (nevezano, ali zar slicni takav dictionary sa tipovima nema i IoC kontejner?) se traže pretplatnici na određeni tip poruke, i svakom pretplatniku onda se šalje ta poruka. Ako se netko pretplatio na baznu klasu poruke (MessageBase), dobiti će sve poruke, jer sve poruke nasljeđuju baznu poruku. Logično, zar ne;)?
IReceiver interface koji moraju implementirati objekti koji žele dobivati poruke je jednostavan, kao i bazna MessageBase klasa:

public interface IReceiver
{
    void ReceiveMessage(MessageBase messsage);
}

public abstract class MessageBase
{
    public MessageBase(object sender)
    {
        Sender = sender;
    }

    public object Sender { get; protected set; }
}

/// <summary>
/// Primjer implementacije poruke
/// </summary>
public class ChatMessage : MessageBase
{
    public ChatMessage(object sender, string text) : base(sender)
    {
        Text = text;
    }

    public string Text { get; private set; }
}

Bazna ViewModel klasa, koju nasljeđuju sve ViewModel klase, sadrži logiku pretplate, primanja i slanja poruka mediator objektu:

public abstract class ViewModelBase : INotifyPropertyChanged, IReceiver
{
    protected void Subscribe(Type messageType)
    {
        MessengerInstance.Subscribe(this,messageType);
    }

    protected void Publish(MessageBase message)
    {
        MessengerInstance.Publish(message);
    }
        
    private MessageGateway MessengerInstance
    {
        get { return MessageGateway.Instance; }

    }

    public virtual void ReceiveMessage(MessageBase messsage) { }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

kao što je vidljivo iz primjera, ViewModelBase apstraktna klasa ujedno je i IReceiver, znači se može pretplatiti na primanje poruka.
Da bi pretplatili na određene poruke, dovoljno je dodati u konstruktor našeg ViewModel-a (npr. DashboardViewModel, koji nasljeđuje ViewModelBase):

Subscribe(typeof(ChatMessage));

Za primanje poruka napravimo override ReceiveMessage metode:

public override void ReceiveMessage(MessageBase messsage)
{
    var chatmsg=(ChatMessage)message;
    // operacije nad primljenom porukom
}

Primjer slanja nove poruke:

Publish(new ChatMessage(this,"neki text"));

Cijeli projekt možete i skinuti lokalno, pa će sama implementacija biti jasnija, nadam se. 

Čisto za informaciju, slična arhitektura i način slanja poruka se koristi i u Service Bus frameworcima, pogodnim za SOA arhitekturu. Microsoft nema svoj ServiceBus framework (osim promoviranja JBOWS!), za razliku od Java svijeta, gdje su oni dosta popularni u enterprise primjeni. Bitna razlika od ove implementacije je asinkroni način slanja poruka putem Queue (MSMQ uglavnom), kojeg u ovom primjeru nema (sve je sinkrono, nema “reda” poruka i enkapsuliranja u transakcije), kao i “broker” objekt koji može sadržavati određenu logiku koja određuje kome se mora poslati koja poruka ovisno o danim parametrima. Dva popularna open source frameworka u .NET svijetu su nServiceBus i MassTransit, a uskoro se nadam da ću imati prilike i pozabaviti se i njima, nakon čeka naravno slijedi blog osvrt!

Download Silverlight projekta sa primjerom Mediator i MVVM patterna
(Download of Silverlight project with example of Mediator and MVVM patterns)