Pokazywanie postów oznaczonych etykietą binding. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą binding. Pokaż wszystkie posty

czwartek, 29 października 2015

[MessageQueues] RabbitMQ

RabbitMQ jest open-source'owym message brokerem zbudowanym w oparciu o standard AMQP w języku Erlang. Jego główne cechy wyróżniające go spośród innych rozwiązan tej klasy to:
- high availability
- clustering
- zarządzianie (web UI)
- security (autentykacja, uprawnienia)

Aby rozpocząć pracę z RMQ należy pobrać i zainstalować go ze strony. Aby uruchomić instalator należy wcześniej pobrać i zainstalować dystrybucję Erlanga. Obie instalacje warto przeprowadzać jako administrator systemu (unikniemy problemów z cookie Erlanga). RabbitMQ dostarcza przyjazny interfejs webowy na porcie 15672. Aby móc z niego skorzystać należy wywołać polecenie:
rabbitmq-plugins enable rabbitmq_management

AMQP (Advanced Message Queue Protocol) jest otwartym standarded dla messagingu, niezależnym od producenta. Opiera się o następujące koncepcje:
- message broker - scentralizowany serwer pośredniczący
- exchanges :
 - direct (do konkretnej kolejki)
 - fan-out (do wielu kolejek)
 - topic (routing na podstawie wyrażen tekstowych)
 - headers (routing na podstawie nagłówków)

Exchange transferuje wiadomość do kolejek. Każda kolejka ma przypisany jakiś exchange poprzez mechanizm bindingu.

Kolejki i exchange można zakładać zarówno w proceduralnym kodzie jak i w UI administracyjnym, wyklikując odpowiednie opcje:



W projekcie .NET-owym należy zainstalować nugetem pakiet klienta RabbitMQ:



Najprostszy kod wstawiający do nazwanej kolejki poprzez domyślny exchange wygląda następująco:


var connectionFac = new ConnectionFactory()
{
    HostName = "192.168.1.5",
    UserName = "admin",
    Password = "admin1",
    VirtualHost = "/"
};

var connection = connectionFac.CreateConnection();
var model = connection.CreateModel();

var properties = model.CreateBasicProperties();
properties.SetPersistent(true);

var bytes = Encoding.UTF8.GetBytes("my message");

var queue = "myqueue";
var exchange = ""; //default

model.BasicPublish(exchange, queue, properties, bytes);

Console.ReadKey();
W przypadku połączen spoza localhost musimy założyć swojego usera (takiego jak admin) i nadać mu uprawnienia do vhosta.

Przykład kodu czytającego wiadomości:

model.BasicQos(0, 1, false); //przetwarzany po jednej wiadomości

var consumer = new QueueingBasicConsumer();
model.BasicConsume("myqueue", false, consumer);

while (true)
{
    var delArgs = consumer.Queue.Dequeue();
    byte[] bytes = delArgs.Body;
    Console.WriteLine(Encoding.UTF8.GetString(bytes));
    model.BasicAck(delArgs.DeliveryTag, false);
}

Procesów słuchających można uruchomić wiele przypisanych do tej samej kolejki. Będą wtedy rywalizowały o pobranie wiadomości. Jeśli chcemy, by kolejka działało jako publish / subscribe, to powinniśmy zbindować nasze kolejki do odpowiedniego exchange (typu fanout). Po założeniu takiego exchange'a możemy to skonfigurować w UI administracyjnym:

W kodzie po stronie wstawiającej należy ustawić odpowiedni, nazwany exchange, routing key tym razem nie będzie nazwą kolejki, ale pustym stringiem.

Po stronie odbierającej wiadomości mamy kilka zmian:

model.QueueBind("sub1", "my_fanout_exchange", "");
var subscriber = new EventingBasicConsumer(model);

subscriber.Received += (mod, ea) =>
{
    var body = ea.Body;
    var message = Encoding.UTF8.GetString(body);
    Console.WriteLine(" [x] {0}", message);
};

model.BasicConsume(queue: "sub1", noAck: true, consumer: subscriber);
break;

Pozostałe wzorce komunikacyjne w RabbitMQ:

  1. RPC -  wiadomość jest wysyłana do kolejki przez default Exchange, ale zawiera resposne queue, odbiorca dostaje wiadomość i umieszcza odpowiedź w reponse queue
  2. Routing - consumers zbindowani po kluczu, producent wysyła wiadomość z kluczem, a następnie na podstawie tego klucza wiadomość jest przekazywana do jednej lub więcej kolejek.
  3. Topic może zawierać wyrażenie tekstowe a'la regex wyliczane na podstawie znaków * (dowolny znak) i # (zero lub więcej słów). Wyrażeniem tym przetwarzany jest RoutingKey. Przykładowe topiki to: *.high.* lub corporate.#.
  4. Headers: nazwany exchange, wiadomość zawiera nagłówki (tekstowe), warunkiem może być all lub any. Umożliwia matchowanie po jednym lub każdym headerze (własności wiadomości). Analogia do tagowania postów
  5. Scatter Gather - producent wstawia wiadomość do kolejki, tworzy tymczasową kolejkę odpowiedzi. Wielu przetwarzających pobiera dane, przetwarza i wstawia swoje odpowiedzi do response queue. 

poniedziałek, 28 października 2013

[WCF] Address, Binding

Zdefiniowanie serwisu WCF wymaga określenie tzw. ABC, czyli adresu, bindingów i kontraktu, które odpowiadają na pytania gdzie ? jak ? i co ?

Adres definiuje, gdzie serwis jest hostowany. WCF wspiera różne sposoby przesyłania danych, a co za tym idzie różne są rodzaje adresów. Poniższa tabela przedstawia sposoby adresowania w WCF.

Technologia Przykładowy adres Opis
HTTP http://localhost:8001 Najczęściej używany tekstowy sposób przesyłania danych, dane przeważnie w XML lub JSON
HTTPS https://localhost:8001 Bezpieczny sposób przesyłania danych po HTTP. Szyfrowanie za pomocą TLS lub SSL.
TCP Peer network net.tcp://localhost:8002/Service1, net.p2p://localhost/ Bardzo szybki sposób przesyłania danych w formacie binarnym.
IPC (Inter-process communication over named pipes) net.pipe://localhost/PipeService1 Szybki sposób przesyłania danych w obrębie jednej maszyny (współdzielona pamięć).
MSMQ (Microsoft Message Queue) net.msmq://localhost Wiadomości wysyłane przez klienta są kolejkowane. Użyteczny sposób dla scenariuszy, w których istnieje możliwość rozłączenia klienta z serwerem.

Kluczowym elementem architektury WCF jest binding, odpowiadający na pytanie "jak?". Główne obszary, jakie definiuje binding to protokół transportu danych, format wiadomości oraz szczegóły przesyłania wiadomości specyficzne dla danego protokołu. WCF udostępnia szereg protokołów, niemniej jednak zawsze istnieje możliwość zdefiniowania własnego.Poniżej przedstawiono listę bindingów dostarczanych przez WCF. Te, które rozpoczynają się od przedrostka "net" są dedykowane dla technologii .NET, z kolei bindingi rozpoczynające się od "ws" reprezentują ogólnie przyjęte standardy implementowane w wielu technologiach.

Binding Opis
basicHttpBinding Wiadomości przesyłane po Http i zakodowane w Utf-8. Oparte na WS-I profile.
webHttpBinding Serwisy wystawiane jako requesty Http, format XML lub JSON umożliwia tworzenie serwisów w oparciu o wzorzec REST.
wsHttpBinding Korzysta z zaawansowanych profili WS-*, takich jak WS-Security, WS-Transactions, WS-BusinessActivity, etc.
wsDualHttpBinding Korzysta z tych samych profili, co wsHttpBinding ale wspiera komunikację typu duplex.
wsFederationHttpBinding Profile WS-* rozszerzone o federated identity.
netTcpBinding Wiadomości binarne przesyłane po TCP. Wymaga, aby obie strony korzystały z WCF.
netNamedPipeBinding Zoptymalizowany pod kątem komunikacji w obrębie jednej maszyny.
netPeerTcpBinding Komunikacja po TCP z wykorzystaniem technologii P2P.
netMsmqBinding Asynchroniczna komunikacja z wykorzystaniem kolejki komunikatów.

Bindingi można ustawiać w sposób proceduralny...

ServiceHost host = new ServiceHost(typeof(EvaluationService));

host.AddServiceEndpoint(typeof (IEvaluationService), 
    new BasicHttpBinding(), "http://localhost:8080/evals/");

...ale znacznie wygodniej jest robić to w ustawieniach projektu (App.config lub Web.config), gdzie mamy do dyspozycji narzędzie wbudowane w Visual Studio.


W oknie tym możemy ustawić behavior dla określonego typu bindingu zmieniając domyślne parametry. Po zamknięciu okna zmiany zostaną przeniesione do pliku XML z konfiguracją. Na przykład:

<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="MyBindingConfiguration" allowCookies="true" />
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="EvaluationServiceLibrary.EvaluationService">
        <endpoint address="/evals/" binding="wsHttpBinding" bindingConfiguration="MyBindingConfiguration"
          contract="EvaluationServiceLibrary.IEvaluationService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

niedziela, 23 września 2012

[HTML|JS|CSS] KnockoutJS : Custom Binding

KnockoutJS umożliwia tworzenie data bindingu według własnych reguł. Ponadto programista ma możliwość tworzenia reużywalnych ViewModeli, gdzie dane mogą być przekazywane np. poprzez argumenty. Poniższy przykład wykorzystuje te zagadnienia.

<h3 data-bind="text: question"></h3> 
<table>
    <thead><tr><th>Option</th></thead>
    <tbody data-bind="foreach: answers">
        <tr>
            <td data-bind="text: answerText"></td>             
        </tr>    
    </tbody>
</table>
<h3>Your answer:</h3>
<select data-bind="options: letters, value: answer"></select>
<button data-bind="slideBinding: isAnswered() > 0">Finished</button>

Dla przycisku zdefiniowany został specjalny rodzaj bindingu nazwany slideBinding.Aby utworzyć taki binding należy w pliku ze skryptem dodać odpowiedni obiekt slideBinding w ko.bindingHandlers

ko.bindingHandlers.slideBinding = {
  init: function(element, valueAccessor) {
        var shouldDisplay = valueAccessor();
        $(element).css('display','none');
    },
    update: function(element, valueAccessor) {
        var shouldDisplay = valueAccessor();
        shouldDisplay ? $(element).slideDown() : $(element).slideUp();
    }
};

Należy zdefiniować funkcje dla inicjalizacji i zmiany którejś z zależności. Pod valueAccessor dostępne jest wyrażenie logiczne podawane w widoku ( w tym przypadku isAnswered() > 0). Wewnątrz obu funkcji można wykonywać operacje na elemencie, w tym przypadku przy użyciu biblioteki jQuery.

Pozostała część ViewModelu odpowiada za przetworzenie wartości podawanych jako argumenty w odpowiednie properties. Kontrolkę można tworzyć w wielu kontekstach podając za każdym razem inne pytanie i zestaw odpowiedzi.

function answerText(text){
    this.answerText = text;
}

function QuizViewModel(question,answers){
    var self = this;
    self.question = ko.observable(question);
    self.answers = $.map(answers,function(text){return new answerText(text)})
    self.answer = ko.observable("");    
    self.letters = ko.observableArray(["","a","b","c","d"]);                 

    this.isAnswered = ko.computed(function() {
        if(self.answer()===""){ return 0; }
        else{ return 1; }       
    },this);
}

ko.applyBindings(new QuizViewModel("Capital city of Ecuador",
    ["Quito","La Paz","Caracas","Lima"]));

niedziela, 26 sierpnia 2012

[WPF] HierarchicalDataTemplate

Podczas stosowanie data bindingu, dane mogą być nam dostarczone w różnej postaci. Mogą to być pojedyncze wartości, kolekcje przeróżnych typów, ale często zdarzy się, że są dostarczone w postaci hierarchicznej. WPF ułatwia bindowanie się do plików XML, za pomocą specjalnych mechanizmów.Pierwszy z nich do XmlDataProvider zapewniający binding i notyfikację każdej zmiany, jaka zajdzie po obu stronach. Kolejnym jest HierarchicalDataTemplate, który umożliwia binding do hierarchicznej struktury.

Mając przykładowe dane w pliku Countries.xml:


<?xml version="1.0" encoding="utf-8" ?>
<Countries>
  <Country Name="Poland">
    <CapitalCity>Warsaw</CapitalCity>
    <Voivodeships>
      <Voivodeship Name="Masovian">
        <Cities>
          <City>Plock</City>
          <City>Radom</City>
          <City>Warsaw</City>
        </Cities>
      </Voivodeship>
      <Voivodeship Name="Lesser Poland">
        <Cities>
          <City>Cracow</City>
          <City>Tarnow</City>
        </Cities>
      </Voivodeship>
      <Voivodeship Name="Greater Poland">
        <Cities>
          <City>Kalisz</City>
          <City>Poznan</City>
        </Cities>
      </Voivodeship>      
    </Voivodeships>  
</Country>
</Countries>

Możemy do resourców dodać XmlProvider z ścieżką do pliku.

<XmlDataProvider Source="Countries.xml" XPath="Countries" x:Key="MyProvider" />

A następnie, również w resourcach dodać hierarchiczny szablon danych.


<HierarchicalDataTemplate DataType="Countries" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="Countries" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Country" ItemsSource="{Binding XPath=*}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding XPath=@Name}" />
        <TextBlock Text=", Capital City : " />                
        <TextBlock Text="{Binding XPath=CapitalCity}" />
    </StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Voivodeships" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="Voivodeships :" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Voivodeship" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="{Binding XPath=@Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="Cities" ItemsSource="{Binding XPath=*}">
    <TextBlock Text="Cities" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="City" >
    <TextBlock Text="{Binding XPath=.}" />
</HierarchicalDataTemplate>

Ostatecznie możemy zbindować dane z providera do kontrolki TreeView.


 <TreeView ItemsSource="{Binding Source={StaticResource ResourceKey=MyProvider}, XPath=.}"  />

I tym sposobem możemy przeglądać drzewo z naszymi danymi zapisanymi w takiej hierarchii, jak w pliku XML

piątek, 24 sierpnia 2012

[WPF] Data Binding : Value Converter

Używając data bindingu może zajść potrzeba zbindowania dwóch różnych typów. Innym razem możemy chcieć dodać pewne reguły walidacji bindowanych danych, np. saturację wartości liczbowych. Te zadania wymagają stworzenia własnego Value Convertera - specjalnej klasy, zawierającej logikę konwertującą, czy walidującą.

W pierwszym kroku należy zdefiniować klasę implementującą interfejs IValueConverter.

 public class DigitToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            float res = 0;
            bool valid = float.TryParse(value.ToString(), out res);
            if(valid)
            {
                var props = typeof(Colors).GetProperties();
                try
                {
                    return new SolidColorBrush(Color.FromRgb((byte)res, 0, 0));
                }
                catch (Exception)
                {
                    return new SolidColorBrush(Color.FromRgb(0, 0, 0));
                }
            }
            return Brushes.Wheat;

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

Jeżeli interesuje nas binding w jedną stronę, metody ConvertBack nie trzeba implementować.

Następnie należy dodać do zasobów okna nasz konwerter.

<Window.Resources>
        <local:DigitToBrushConverter x:Key="myConverter" />
</Window.Resources>

Utworzona zostanie instancja konwertera, którą można przywoływać, jako StaticResource.

W końcu można przejść w xaml do stworzenia bindingu.


<Slider x:Name="colorSlider"  />
<Button Background="{Binding ElementName=colorSlider, Converter={StaticResource myConverter}, Path=Value}" 
Content="BoundBackground" />
   

Dodatkową opcją jest ConverterParameter - obiekt, który będzie przekazany do metody konwertera.jako parameter.

[WPF] Data Binding : Relative Source

Ustawiając w xaml data binding, możemy określić źródło korzystając z RelativeSource. Istnieje kilka sytuacji, w których warto użyć tej opcji.

  • Gdy chcemy, aby źródło i cel bindingu były tą samą kontrolką, np. zmiana wartości slidera powoduje zmianę jego nieprzezroczystości.
<Slider Minimum="0.1" Maximum="1" TickFrequency="0.1"
   Value="{Binding Path=Opacity, RelativeSource={RelativeSource Self}}" />

  • Podczas tworzenia CustomControl w WPF, dodajemy do niej styl w pliku Generic.xaml. Custom control może składać się z wielu mniejszych kontrolek i gdy chcemy aby taka kontrolka bindowała się do property z CustomControl, używamy RelativeSource TemplatedParent.

<Style TargetType="{x:Type local:MySimpleCustomControl}">
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MySimpleCustomControl}">
                    <Grid Margin="3">                     
                        <Border BorderThickness="1" BorderBrush="Gray" 
                            Margin="2" Grid.RowSpan="2" 
                            VerticalAlignment="Center" HorizontalAlignment="Stretch">
                            <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Margin}" 
                                Width="60" TextAlignment="Right" Padding="5"/>
                        </Border>                      

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

...możemy stworzyć instancję takiej kontrolki, ustawić jej marginesy i zostaną one zbindowane do textblocka.
  • Czasami zachodzi potrzeba zbindowania się do property z kontrolki, która znajduje się wyżej w drzewie wizualnym. Możemy znaleźć najbliższego przodka danego typu.

<TextBlock Text="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}}" />

Istnieje także możliwość określenie, który z kolei przodek nas interesuje, dopisując AncestorLevel=...

środa, 15 sierpnia 2012

[WPF] Dependency Property

Jedną z najważniejszych koncepcji w WPF jest Dependency Property. Umożliwiają one stylowanie, automatyczny data binding czy animowanie dowolnych właściwości. Dependency Property może być zmieniane przez wiele obiektów jednocześnie, a jego największą zaletą jest wbudowana zdolność do notyfikowania o zmianach wartości. DP mogą być także zmieniane z poziomu xaml co jest następną ich zaletą. Zatem przy tworzeniu własnych kontrolek jest to bardzo wygodne rozwiązanie. Kolejną korzyścią wynikającą z zastosowania DP jest możliwosć zdefiniowania Property Triggerów - warunkowych akcji wykonywanych, gdy property osiągnie pewną wartość

Od strony języka DP są propertiesami, budowanymi w dość nietypowy sposób. Należy dodać do klasy kontrolki statyczne publiczne pole tylko do odczytu, gdzie nazwa to nazwa property z dodanym "Property". Następnie w statycznym konstruktorze rejestruje się DP za pomocą metody DependencyProperty.Register. Przez parametry tej metody można określić domyślną wartość i metodę wołaną przy zmianie wartości. Można także zdefiniować pewien "wrapper", który będzie opakowywał ustawianie i odczyt wartości DP.

W poniższym przykładzie dla kontrolki tykającego zegarka zdefiniowano Dependency Property Ticks, które reprezentuje liczbę uderzeń zegarka.

 public partial class TickingTimer : UserControl
    {

        public static readonly DependencyProperty TicksProperty;

        public int Ticks
        {
            get { return (int)GetValue(TickingTimer.TicksProperty); }
            set { SetValue(TickingTimer.TicksProperty, value); }
        }

        static TickingTimer()
        {
            TickingTimer.TicksProperty = DependencyProperty.Register("Ticks",
                typeof(int), typeof(TickingTimer),
                new FrameworkPropertyMetadata(0,
                new PropertyChangedCallback(OnTicksChanged)));
        }

        private static void OnTicksChanged(DependencyObject o, DependencyPropertyChangedEventArgs eventArgs)
        {
            Console.Beep();
        }
//LOGIKA KONTROLKI
     }

Kontrolkę taką można dodać do okna i zbindować się do naszego Dependency Property Ticks.

<Window x:Class="Dependency_Property.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:Dependency_Property="clr-namespace:Dependency_Property" 
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Dependency_Property:TickingTimer x:Name="Timer" Ticks="5" />
        <Label Content="{Binding ElementName=Timer,  Path=Ticks}" />
    </Grid>
</Window>