Jump to content
  • Announcements

    • Xmat

      Pravidlo pro postování v TTT

      Do sekce Tipy, triky, tutoriály nepatří žádné dotazy.   Postujte sem vaše návody, tipy a různé další věci jež uznáte za vhodné sdělit zdejšímu osazenstvu, ale veškeré dotazy směřujte do sekce Všeobecná diskuse.
    • Replik

      Seznam návodů a důležitých témat v této sekci

      Pro lepší přehlednost jsem vytvořil tento seznam, který vás, méně zkušené, lépe provede touto sekcí. Věřím, že zde najdete, co hledáte. Vypsané jsou návody, které jsou oficiálně uznané jako návody. Běžné diskuze, které neposkytují postupy a rady zvěřejněny nejsou.   Instalace vlastního MaNGOS Serveru Díky těmto návodům budete (měli by jste být) schopni vytvořit a následně spustit váš vlastní server. Nastavení je pro verze s i bez datadisku.   Instalace MaNGOS Serveru (bez datadisku TBC) - Autor Benny Instalace MaNGOS Serveru (s datadiskem TBC) - Autor Malfik Instalace MaNGOS Serveru v prostředí Linux - Autor charlie Instalace MaNGOS Serveru v prostředí Linux - Autor kupkoid   Chyby a jejich řešení při přihlašování k serveru - Autor Cybe   Zálohování uživatelských dat   Dávkový soubor (BAT soubor) pro vytvoření SQL záloh - Autor Replik   Kompilování - tvoření vlastních release (revizí)   Tvorba kompilací pro Win32 (MangoScript) - Autor bLuma   Ostatní - těžko zařaditelné, ale neznamená to, že nejsou dobré   VIP Systém - Autor charlie Tvorba Webových stránek pro MaNGOS - Autor zahuba Tvorba teleportačních NPC (MangoScript) - Autor Replik Registrační web (původně předělaná SPORA) Funkční pro Antrix i MaNGOS - Autor Replik Nastavení a spuštění Minimanager pro MaNGOS - Autor BlackMartin Nastavení MaNGOS Website - Autor Artorius   Samozřejmě jsou zde i jiné návody, ale tyto jsou nejvíce používané, proto věřím, že vám budou nápomocné. Tuto sekci budeme upravovat podle potřeby. Pokud by jste něco nenašli nebo si nevěděli rady, hledejte na fóru a teprve potom založte vlastní topik. Pokud nějaký autor vytvoří kvalitní návod a chtěl by ho zveřejnit i v tomto seznamu, doporučuji, aby mi napsal zprávu skrze PM.   Díky a přeji hezký den na WoWResource   Replik
    • Aristo

      Příspěvky tam, kde nemají co dělat

      Dodržujte zákaz přispívání do topiků s repaky pokud si to zakladatelé nepřejí!! Opakované psaní příspěvků bude trestáno warnem.
    • Aristo

      Používání spoilerů

      Poslední dobou má většina uživatelů fora zvláštní nutkání postovat extrémně dlouhé texty nebo kódy, které zabírají v nejedenom případu i 80% obsahu celé stránky a hodně tak zvedají nepřehlednost v topiku. Chtěl bych všechny uživatele požádat, aby při postování citací, jakýchkoliv kódů, errorů, atp... delších než 30 řádků používali funkci spoileru.   Funkci vyvoláte příkazem [spoiler] text [/spoiler]   Ukázka:  
ntdrt

World of Warcraft Server API - revoluce komunikace webu s wow serverem?

Recommended Posts

Je to už celkem dlouho, co jsem měl tenhle nápad, k realizaci jsem se dostal ale až dnes, tak jsem něco sepsal.

 

Upozornění:

Tohle je pre-alfa developerská verze, má jen ukázat mojí myšlenku v praxi, ověřit zájem a použitelnost.

 

Popis pro uživatele:

Řešení má pár výhod, je bezpečné, je také rychlé, oproti klasickým řešení je kratší. Vás vůbec nemusí zajmat struktura databáze nebo jak získat data z databáze, na vás je jen zakomponovat vrácený výsledek do vaší stránky, tedy HTML :).

 

Popis pro developery:

Lehce rozšiřitelný framework který většinu práce obstará za vás. Je nezávislý, je mu jedno na jakém databázovém systému běží nebo jaky používáte emulator. Využívá systém ovladačů který má jesně danou strukturu, napsaní ovladače na váš emulator znamená prakticky napsat SQL datazy které bude framerowk volat, žádné mysql_query, žádné ošetřování. Stačí prostý text.

 

Používé objektový model, dále tzvn. lazy loading = co nepotřebujete to framework zbytečně nenačítá, co potřebujete často, urychlí intergovaná vyrovnávací pamět.

 

Další featurou je meziukládání náročných operací.

 

V tomto případě status serveru, když je server off-line a PHP se pokouší navázat spojení, tak web se zaseká. Proč? Jelikož když se navazuje spojení tak script má určitou dobu za kterou musí vzdálený server odpovědět, tato doba je ale dlouhá a proto se stránka načítá klidně několik sekund (v normálním stavu server odpoví v řádu milisekund). Aneb když spadne server, tak spadne i web.

 

Takže status se neověřuje furt ale jen jednou za 30 sekund, při výpadku bude první náštevník mít web spomalený, ale druhý už ne.

 

Ukázka:

Pro ukázku uvádím Mysql driver a emulátor TrinityCore (jiné ovladače zatím neexistují). Popis kódu mluví za vše, kdyby se to ujalo další funkce by mohli být: registrace, výpis online hráčů a cokoliv dalšího co je na webu potřeba :).

 

<?php
// krok 1: nacteme knihovny
require_once dirname(__FILE__)."/WApi/WApiLoader.php";

// krok 2: vytvorime konfiguraci
$config = array(
 "driver"      => "Mysql",           // databazovy server
 "emulator"    => "TrinityCore",     // druh emulatoru
 "server"      => "localhost",       // databazovy server
 "user"        => "local",           // uzivatel
 "password"    => "local",           // heslo
 "auth"        => "wow_auth",        // databaze realmu
 "characters"  => "wow_characters",  // databaze charakteru
 "world"       => "wow_world",       // databaze worldu
 "status"      => array(             // konfigurace statusu, IP + PORT world serveru
   "ip"    => "127.0.0.1",
   "port"  => 8085,
 ),
);

// krok 3: vytvorime instanci a nacteme konfiguraci
$api = new WApi($config);

// krok 4: libovne pouzivame 

// nasledujici funkce vypisou vzdy cislo, tedy pocet
echo "Počet online hráčů: ".$api->countOnline()."<br />";
echo "Počet online hordy: ".$api->countOnlineHorde()."<br />";
echo "Počet online aliance: ".$api->countOnlineAlliance()."<br />";
echo "Počet online gm: ".$api->countOnlineGm()."<br />";

// nasledujici funkce vypise jednu z hodnot: online / offline
echo "Server je ".$api->getStatus()."<br />";

// to je vse, vic jsem nestihl 

Doufám že to pro pochopení stačí.

 

Instalace:

Stačí nakopírovat knihovnu (tedy celou složku WApi z archivu) do vašeho webu.

Potom použít dle scriptu nahoře.

 

Licence:

Projekt je uvolněn pod licencí GPL - http://cs.wikipedia.org/wiki/GNU_General_Public_License

 

Stručně řečeno, program je zdarma, je opensource, program můžete kopírovat, upravovat, cokoliv co chcete.

ALE při využití programu nebo jenom jeho částí váš projekt spadá automaticky pod stejnou licenci, tedy GPL.

 

Ještě stručněji: je zakázáno cokoliv z programu prodat :)

 

Získání:

Aktuální verze je vždy na bitbucket - https://bitbucket.org/wtfko/wowapi/

 

Cíl:

Univerzální framework co obstará vše kolem spojení vašeho webu a serveru.

Edited by ntdrt
  • Upvote 1

Share this post


Link to post
Share on other sites

Vypadá to zajímavě, ale u většiny lidí to povede ke zbytečnému zvýšení zátěže db. Protože to udělají jako ve tvém příkladu a místo jednoho dotazu na počty hráčů použijí hned tři... Tím, že to degraduješ na předávání SQL dotazů neumožníš žádné mezi výpočty nebo v aktuálním stavu vracení více výsledků (TOP10 aj.).

 

Lazy loading tam opravdu nemáš.

require_once WAPI_DIR."/WApiInterfaces.php";

require_once WAPI_DIR."/WApiExceptions.php";

require_once WAPI_DIR."/WApiDrivers.php";

require_once WAPI_DIR."/WApiEmulators.php";

require_once WAPI_DIR."/WApiStorage.php";

require_once WAPI_DIR."/WApi.php";

 

To cachování prakticky nemá význam. Takovýhle dotaz použiješ na stránce jednou možná dvakrát a mezi různými HTTP requesty to necachuješ. Dobře napsaný web to nepoužije vůbec.

 

Nápad zajímavý, ale z mého pohledu to není momentálně dobrá koncepce/architektura.

  • Upvote 2

Share this post


Link to post
Share on other sites

Hned na úvod pre-alfa dev verze - není to určeno hodit hned na web :). I tak je to kvalitnou hodně nad běžným webem serveru, né že né.

 

Vypadá to zajímavě, ale u většiny lidí to povede ke zbytečnému zvýšení zátěže db. Protože to udělají jako ve tvém příkladu a místo jednoho dotazu na počty hráčů použijí hned tři... Tím, že to degraduješ na předávání SQL dotazů neumožníš žádné mezi výpočty nebo v aktuálním stavu vracení více výsledků (TOP10 aj.).

Dotaz by jsi ušetřil leda u součtu na statusu, nicméně lepší jeden optimalizovanej dotaz než sčítání pomocí mysql_num_rows nebo ještě huře.

EDIT: https://bitbucket.org/wtfko/wowapi/src/0632912cec34/WApi/WApi.php#cl-31 lepší a zároveň univerzální řešení neexistuje.

 

 

Lazy loading tam opravdu nemáš.

Pleteš si lazy-loading a autoloading. Lazy-loading tam je, viz storage.

A dělat loader kvůli třem třídám je IMHO zbytečný, nehledě že ho neměli (snad ani nemají) i giganti jako je Zend což je tvůrce PHP. Důvod je jednoduchý, (například) memcache + autoloading = větší zatížení, než v případě require_once. Navíc, já potřebuju VŠECHNY třídy.

 

Tohle řeší skoro všude vlastním loaderem, aneb velká mrcha co naloaduje všechno co najde. Ale tam se jedná o stovky souborů, právě u větších FW.

 

To cachování prakticky nemá význam. Takovýhle dotaz použiješ na stránce jednou možná dvakrát a mezi různými HTTP requesty to necachuješ. Dobře napsaný web to nepoužije vůbec.

Jinak vše co jde do databáze serveru má projít přes cache. Teď tam je Array ale má tam být file storage, viz TODO. Tím výkon naroste a i kdybych poslal 5 zbytečných dotazů. Tak aplikace bude rychlejší. Ale to už je složitější záležitost proto jsem to nenapsal hned. Doděláno

Edited by ntdrt

Share this post


Link to post
Share on other sites

Dotaz by jsi ušetřil leda u součtu na statusu, nicméně lepší jeden optimalizovanej dotaz než sčítání pomocí mysql_num_rows nebo ještě huře.

EDIT: https://bitbucket.org/wtfko/wowapi/src/0632912cec34/WApi/WApi.php#cl-31 lepší a zároveň univerzální řešení neexistuje.

Za optimalizovaný dotaz bych osobně považoval takový, kterému stačí využít index. Což sloupce online a race nesplňují. Osobně jsem měl na mysli, provést SELECT s GROUP BY a počty týmů a celkový součet sečíst v PHP. Ale o kolik by to bylo rychlejší/pomalejší nebudu spekulovat.

 

Pleteš si lazy-loading a autoloading. Lazy-loading tam je, viz storage.

Ups, tady jsem opravdu prohodil pojem :) Ale jinak výtku mám - singleton u storage není dobré řešení. Pokud budu mít dva realmy stejného emulátoru tak to nebude fungovat.

  • Upvote 1

Share this post


Link to post
Share on other sites

K čemu je GROUP když máš metody na získání frakce oddělené. To by pak cíl aplikace utíkal jinam. Tenhle script má načíst přesně to co potřebuješ, ne nic navíc.

 

Logicky to musí bejt rychlejší, nejde o dotaz ale o počet požadavků.

 

Nedalo mě to a udělal jsem si menší benchmark, tabulku characters jsem naplnil, něco kolem 20 000 záznamů (reálná hodnota). Sčítal jsem tedy frakce, jeden dotaz s GROUP je rychlejší ALE pokud chci jen jednu frakci, mám smůlu, nehledě na délku zdrojového kódu, řešení je strašně moc krkolomný. Viz spoiler, myslel jsi to takhle?

 

Testováno samozřejmě v CLI (PHP 5.3.6 (cli) (built: Mar 17 2011 10:37:07)) za pomocí C2D @ 1,8Ghz se starou architekturou:

 

<?php
mysql_connect("localhost", "local", "local");
mysql_select_db("wow_characters");

// insert data
/*mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");
for($number = 1; $number <= 20000; $number++){
 mysql_query("INSERT INTO characters (guid, race, online) VALUES ($number, ".rand(1, 10).", ".rand(0, 1).")");
}
mysql_query("COMMIT");*/

// NOTE: tohle reseni je strasne krolomny, opravdu si to myslel takhle?
echo "== 1x SELECT + GROUP BY ==\n";
$result = 0;
for($loop = 1; $loop <= 10; $loop++){
 echo "LOOP #".$loop.": ";

 $start = microtime(true);
 $query = mysql_query("SELECT SUM(online) AS count, race FROM characters GROUP BY race");
 $horde = 0;
 $alliance = 0;
 while($row = mysql_fetch_assoc($query)){
   switch($row["race"]){
     case 1;
     case 3:
     case 4:
     case 7:
     case 10:
       $horde += $row["count"];
       break;
     case 2:
     case 5:
     case 6:
     case 8:
     case 9:
       $alliance += $row["count"];
       break;
   }
 }
 echo $horde + $alliance;
 $end = microtime(true);

 $time = $end - $start;
 echo " - $time\n";
 $result += $time;
}
echo ($result/10);

echo "\n\n";

echo "== 2x SELECT ==\n";
$result = 0;
for($loop = 1; $loop <= 10; $loop++){
 echo "LOOP #".$loop.": ";

 $start = microtime(true);
 $horde = mysql_result(mysql_query("SELECT SUM(online) FROM characters WHERE race IN (1, 3, 4, 7, 9)"), 0);
 $alliance = mysql_result(mysql_query("SELECT SUM(online) FROM characters WHERE race IN (2, 5, 6, 8, 10)"), 0);
 echo $horde + $alliance;
 $end = microtime(true);

 $time = $end - $start;
 echo " - $time\n";
 $result += $time;
}
echo ($result/10);

 

Výsledky (sekundy):

GROUP: 0.078634023666382

2x SELECT: 0.11130595207214

 

Druhý pokus (1 000 000 záznamů, transakce měla přes 100mb):

GROUP: 7.7149270296097

2x SELECT: 12.241809511185

VNOŘENÝ SELECT: 11.998792600632

 

Závěr: podle mě je elegantnější řešit to 2x SELECTem, alespoň zachovám strukturu a i přes to že je to třetina, nehraje to žádnou roli - jelikož se vše ukláda do paměti. Lepší je přehlednost a jednoduchost, než takova patlanice.

 

Teď cache už smysl má, každých 30 sekund se údaje invalidují (tím i aktualizují).

Tím je nutnost povolit zápis do složky WApi/temp.

 

https://bitbucket.org/wtfko/wowapi/src

Edited by ntdrt

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×