środa, 21 marca 2012

Użytkownicy online

Jednym z ostatnich moich zadań, było przygotowanie statusów użytkowników, które będą określały czy dany użytkownik jest online, czy też nie.

Projekt, w którym to realizuje korzysta z cachowania przy pomocy Redis'a, o którym pisałam we wcześniejszym poście. Funkcje są funkcjami wcześniej omawianymi z klasy RedisCache.

Z uwagi na to, że sesja również przechowywana jest w Redisie, korzystam w moim projekcie .NET z własnego provider'a sesji. Na początku myślałam, że będę mogła dodawać identyfikatory użytkowników do listy w cache'u przy logowaniu lub w zdarzeniu Session_Start w Global.asax i usuwać przy wylogowaniu bądź przy wywołaniu zdarzenia Session_End. Niestety, przy korzystaniu z własnego provider'a sesji zdarzenie Session_End nie będzie nigdy wywoływane.
Tak więc zrobiłam to inaczej, każdy użytkownik będzie przechowywany w redisie jako osobny klucz z wartością "1" jeśli jest dostępny. Klucz ten będzie dodawany bądź aktualizowany przy logowaniu i w każdym kontrolerze widoków projektu. Natomiast czas wygaśnięcia klucza zostanie ustawiony na 10 minut.


public static void DodajUzytkownikaOnline(string id)
        {
                string klucz = String.Format("online-{0}", id);
                RedisCacheProvider.RedisCache.Set<string>(klucz, "1", DateTime.Now.AddMinutes(10));
        }

        public static void UsunUzytkownikaOnline(string id)
        {
                 string klucz = String.Format("online-{0}", id);
                 RedisCacheProvider.RedisCache.Remove(klucz);
        }



public static bool CzyOnline(string id)
        {
                string klucz = String.Format("online-{0}", id);
                string status = RedisCacheProvider.RedisCache.Get<string>(klucz);
                if (status == "1")
                    return true;
                else
                    return false;
        }


Redis Cache Provider

Redis jest to bardzo proste narzędzie, które pozwala cachować dane, które często pobieramy z bazy, a ich stan nie ulega zbyt często zmianie, dlatego warto przechowywać je w cache'u. Dane te przechowujemy jako klucz - wartość. Redis pozwala przyspieszyć pobieranie danych, a co za tym idzie czas ładowania strony. Redis udostępniany jest jako open source i można go pobrać z tej strony: http://redis.io/. Po pobraniu redisa uruchamiamy serwer, który domyślnie korzysta z portu 6379. W paczce z serwerem redisa dostępny jest również klient za pomocą którego możemy przetestować polecenia redisa opisane na wyżej wymienionej stronie (dodawania, sprawdzania czy usuwania kluczy).

Aby korzystać z redisa w .NET potrzebna jest odpowiednia biblioteka, którą musimy dołączyć do naszego projektu. Na stronie redisa znajdziemy listę takich bibliotek. Ja korzystam z ServiceStack.Redis dostępnej tutaj.

Projekt RedisCacheProvider posiada klasę RedisCache, w której zawarte są funkcje potrzebne do operacji na redisie, jak np. funkcja Get to pobrania wartości klucza, funkcja Add do dodania klucza z wartością, funkcja Replace do podmiany wartości, Remove do usunięcia, itd.


public class RedisCache
    {
        private static PooledRedisClientManager redisManager = new PooledRedisClientManager("127.0.0.1:6379");

public static T Get<T>(string key)
        {
            T oOutObject;
            using (var rc = redisManager.GetClient()) 
            {
                    oOutObject = rc.Get<T>(key);
            }
            return oOutObject;
        }

        public static void Add<T>(string key, T value, DateTime expirationDate)
        {
            using (var rc = redisManager.GetClient())
            {
                if(value != null)
                    rc.Add<T>(key, value, expirationDate);
            }
        }

public static void Replace<T>(string key, T entry, DateTime expirationDate)
        {
            using (var rc = redisManager.GetClient())
            {
                rc.Replace<T>(key, entry, expirationDate);
            }
        }

public static void Remove(string key)
        {
            using (var rc = redisManager.GetClient())
            {
                rc.Remove(key); 
            }
        }

        public static void Set<T>(string key, T entry, DateTime expirationDate)
        {
            using (var rc = redisManager.GetClient())
            {
                if (rc.Get<T>(key) != null)
                {
                    rc.Replace<T>(key, entry, expirationDate);
                }
                else
                {
                    rc.Add<T>(key, entry, expirationDate);
                }
            }
        }

}

Przykładowo do przechowania w redisie jakiejś wartości, np.
string test = "wartość testowa";

wystarczy wpisać:

RedisCache.Add<string>("klucz_testowy", test, DateTime.Now.AddDays(1));

Wartość pierwsza to klucz (nazwa) pod jaką będzie przechowywana dana wartość w redisie. Drugi parametr to wartość, którą chcemy przechować w redisie, natomiast trzeci określa datę wygaśnięcia klucza. W tym przypadku klucz zostanie usunięty za jeden dzień.

czwartek, 1 marca 2012

jQuery Star Rating Plugin


jQuery Star Rating Plugin w ASP.NET MVC

Dzisiejsze zadanie to dodanie pluginu do oceniania :) 


W internecie można znaleźć wiele gotowych bibliotek w jquery umożliwiających ocenę. Ja skorzystałam z jQuery Star Rating Plugin v3.14 dostępnego tutaj

Plik z widokiem:

<script type="text/javascript" src="<%= Url.Content("~/Scripts/star-rating/jquery.rating.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/Scripts/star-rating/jquery.MetaData.js") %>"></script>
<link rel="stylesheet" type="text/css" href="<%= Url.Content("~/Scripts/star-rating/jquery.rating.css") %>" />


<span class="rating">
      <span style="float: left;">Ocena: </span>
      <span style="">
        <input name="star1" type="radio" class="auto-submit-star" value="1" />
        <input name="star1" type="radio" class="auto-submit-star" value="2"/>
        <input name="star1" type="radio" class="auto-submit-star" value="3"/>
        <input name="star1" type="radio" class="auto-submit-star" value="4"/>
        <input name="star1" type="radio" class="auto-submit-star" value="5"/>
      </span>
   </span>

<script type="text/javascript">

        $(function () {

            $('.auto-submit-star').rating({
                callback: function (value, link) {
                    var data = { idZdjecia: id, ocena: value };
                    $.post('/Zdjecie/Ocen', data, function (result) {
                          alert(result);
                    }, "json");
                }
            });

        });
    </script>




W kontrolerze dodałam odpowiednią akcję do zapisania oceny w bazie danych:

public ActionResult Ocen(int idZdjecia, int ocena)
        {
            string wynik = string.Empty;

            if (Request.IsAuthenticated)
            {
                    /*
                         tutaj funkcje zapisywanie oceny w bazie danych
                   */
                     return Json( "Dziękujemy za ocenę zdjęcia. ");
            }
            else
            {
                return Json("Musisz się zalogować");
            }
        }



W Global.asax dodałam nową trasę:

routes.MapRoute("OcenTemat", "Zdjecia/Ocen", new { controller = "Zdjecia", action = "Ocen" });