Real-time multiplayer Facebook piškvorky – Facebook

Dnes naši připravenou aplikaci umístíme na Facebook. Postupně projdeme všechny jednotlivé kroky.
Seriál: Real-time multiplayer Facebook piškvorky (3 díly)
- Real-time multiplayer Facebook piškvorky 6. 2. 2013
- Real-time multiplayer Facebook piškvorky – real-time multiplayer 11. 2. 2013
- Real-time multiplayer Facebook piškvorky – Facebook 20. 2. 2013
Nálepky:
Abychom mohli piškvorky umístit na Facebook, budeme muset nejdříve vytvořit aplikaci. Nejdříve se přihlaste na https://developers.facebook.com/apps
. Tam klikněte na Vytvořit novou aplikaci.
Zadejte název aplikace (na obrázku pole App Name) a jmenný prostor, kde bude aplikace sídlit (pole Název aplikace, pokud např. zadáte five-in-a-row
, vaše aplikace bude na adrese http://apps.facebook.com/five-in-a-row
).
V základním nastavení aplikace nechte povolen Režim pískoviště. Režim pískoviště znamená, že k aplikaci budou mít přístup pouze vývojáři aplikace a testovací uživatelé. Ze způsobů integrace klikněte na Aplikace na Facebooku, zadejte Canvas URL. Šířku a výšku prostoru použijeme pevnou – 760x600px.
Vpravo klikněte na Developer Roles a vytvořte dva testovací uživatele.
Poté klikněte na Modify a udělejte z uživatelů přátele.
Nakonec ještě upravte v App Details kategorii aplikace na Hry – Stolní hry.
Zdrojové kódy
Stáhnětě si zdrojové kódy 2. dílu:
$ git clone https://github.com/jakubkulhan/xo.git
$ git checkout dil2
Server
Vytvoříme soubor channel.html
a uložíme do adresáře public
:
<script src="//connect.facebook.net/en_US/all.js"></script>
Tento soubor poté využívá Javascript SDK pro komunikaci mezi doménami.
Upravíme server (app.js
), přidáme:
// …
app.get('/channel.html', function (req, res) {
var oneYear = 31536000;
res.set({
'Pragma': 'public',
'Cache-Control': 'max-age=' + oneYear,
'Expires': new Date(Date.now() + oneYear * 1000).toUTCString()
});
res.sendfile(__dirname + '/public/channel.html');
});
Kešování souboru channel.html
je doporučeno nastavit na hodně dlouho, tak to uděláme.
app.all('/xo/', function (req, res) {
res.sendfile(__dirname + '/public/xo.html');
});
// …
Jak jste si určitě všimli, při nastavování aplikace jsme její Canvas URL nastavili na http://localhost:8000/xo/
. Facebook je tvrdohlavý a nenechá vás nastavit Canvas URL na nic jiného, než co končí lomítkem (/
) nebo obsahuje otazník (?
), takže jsme použili cestu /xo/
a budeme na ní servírovat xo.html
.
Facebook na Canvas URL posílá POST požadavek, jenž v těle nese signed_request
. signed_request
obsahuje informace o uživateli, OAuth token ad. My jej nevyužijeme, budeme pracovat čistě s Javascript SDK.
Klient
Z controlleru aplikace odstraníme prompt()
y na zjišťování uživatelských ID hráčů a místo toho použijeme ID uživatele z Facebooku:
// …
window.onFBLogin = function (fbUid) {
uid = fbUid;
socket.emit('uid', uid);
};
// …
window.onFBLogin()
zavoláme, až incializujeme SDK, uživatel se přihlásí a povolí naši aplikaci.
Pro získání ID protihráče použijeme apprequest:
// …
onOverlayButtonClick: function () {
if (uid) {
next();
} else {
var interval = setInterval(function () {
if (uid) {
clearInterval(interval);
next();
}
}, 100);
}
function next() {
FB.ui({
method: 'apprequests',
message: 'Play five in a row with me!',
max_recipients: 1
}, function (response) {
if (response) {
ui.overlay.setText('waiting…');
ui.overlay.hideButton();
socket.emit('waitingFor', response.to[0]);
}
});
}
}
// …
Nejdříve si počkáme, až budeme mít nastavené ID hráče. V tom případě bylo již zavoláno window.onFBLogin()
, SDK bylo incializováno a my s ním můžeme pracovat. FB.ui()
zobrazí dialog v závislosti na dané method
. apprequests
zobrazí dialog na posílání apprequestů. max_recipients
nám udává, že uživatel bude moci vybrat maximálně jednu osobu, které pošle žádost. Pokud uživatel nikoho nevybere a dialog zruší, bude v response
null
. Jinak dostaneme v response
objekt, který bude mimo jiné v to
obsahovat pole s ID uživatelů, jimž byl apprequest odeslán. Takže serveru ohlásíme, že čekáme na hru s vybraným uživatelem.
Poslední částí, již je potřeba změnit, je funkce tryWin()
. Ta místo toho, aby pouze informovala uživatele alert()
em o jeho výhře/prohře, mu dá možnost jeho výsledek sdílet v jeho feedu:
// …
function tryWin(color) {
var win = model.checkWin(color);
if (win) {
socket.emit('end');
ui.squares.cross(win);
ui.overlay.show(function () {
FB.api(opponentUid, function (response) {
FB.ui({
method: 'feed',
name: color === model.myColor ? 'I won :)' : 'I lost :(',
caption: color === model.myColor
? 'I just beat ' + response.name + ' in five in a row!'
: 'I just got beaten by ' + response.name + ' in five in a row…',
link: 'http://apps.facebook.com/five-in-a-row/',
picture: location.protocol + '//' + location.host + '/img/logo.png'
});
});
});
}
}
// …
FB.api()
zprostředkovává přístup ke Graph API. Zjistíme si jméno protihráče, abychom ho mohli zmínit ve zprávě, kterou přidáme do feedu. FB.ui()
s method: 'feed'
zobrazí dialog pro přidání zprávy do feedu uživatele.
Dále musíme do xo.html
přidat načtení a inicializaci Javascript SDK.
<div id="fb-root"></div>
Podobně jako Kinetic.JS potřebuje element, do kterého bude umisťovat jím vytvářené elementy, Javascript SDK potřebuje element s ID fb-root
. fb-root
nesmí být skrytý a nesmí být umístěn v elementu s position: absolute
nebo position: relative
, vkládané elementy jsou pozicované vzhledem k tělu stránky, takže by se nemusely dobře zobrazovat.
<script type="text/javascript">
window.fbAsyncInit = function () {
window.fbAsyncInit()
se zavolá, až se načte Javascript SDK.
FB.init({
appId : '556233954388196',
channelUrl : '//' + location.host + '/channel.html',
status : true,
cookie : true,
xfbml : false
});
FB.init()
inicializuje SDK.
FB.getLoginStatus(onLogin);
function onLogin(response) {
if (!response.authResponse || !response.authResponse.userID) {
FB.login(onLogin, { scope: 'publish_actions' });
} else {
var uid = response.authResponse.userID;
window.onFBLogin(uid);
var options = decodeURIComponent(location.search.slice(1))
.split('&')
.reduce(function _reduce (a, b) {
b = b.split('=');
a[b[0]] = b[1];
return a;
}, {});
if (options.request_ids) {
var requestIds = options.request_ids.split(',');
while (requestIds.length) {
FB.api(requestIds.pop() + '_' + uid, 'delete', function (response) {});
}
}
}
}
};
Až se inicializuje SDK, vyzkoušíme, jestli je uživatel přihlášen a povolil si naši aplikaci (FB.getLoginStatus()
). Jestliže se tak nestalo, bude authResponse
prázdná a uživatel se bude muset přihlásit / povolit naši aplikaci – FB.login()
zobrazí přihlašovací dialog. Jinak máme uživatelovo ID a zavoláme window.onFBLogin()
.
Dále v onLogin()
je kód pro odstranění apprequestů. Apprequesty se neodstraňují automaticky, když na ně uživatel klikne, aplikace se o to musí starat sama. Jestliže jsme pozvali uživatele a ten na Facebook home klikl na zobrazenou žádost/upozornění, aplikace dostane v GET parametru request_ids
seznam ID apprequestů spojený čárkou. Za ID apprequestu musíme přidat podtržítko a naše ID uživatele, abychom mazali apprequest pro konkrétního uživatele (celý apprequest můžeme smazat pouze, jsme-li přihlášeni za aplikaci).
(function(d, debug){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all" + (debug ? "/debug" : "") + ".js";
ref.parentNode.insertBefore(js, ref);
}(document, /*debug*/ false));
</script>
Předchozí kus kód můžete najít přímo na stránkách Javascript SDK. Načte asynchronně všechny potřebné skripty. Ty potom zavolají window.fbAsyncInit()
.
Závěr
Tyto piškvorky využívají jen zlomek z možností, jenž Facebook API nabízí. Avšak při použití Javascript SDK budete prakticky pořád volat FB.ui()
a FB.api()
.
Další zdroje:
Kompletní kód hry po tomto díle:
$ git checkout dil3
Nyní už stačí jen v nastaveních aplikace vypnout Režim pískoviště. Budete muset zadat Secure Canvas URL a servírovat aplikaci přes HTTPS. Ale až tohle uděláte, můžete aplikaci pustit do světa appcentra!
NA tohle jsem čekal. Jen rozchodít https na serveru a jde se do toho.:) Díky moc
Hraju si s integrací OAuth v Drupalu pro přihlášení Facebookem a Twitterem. Problém je, že uživatel je na povolení aplikace na FB i Tw dotazován při každém přihlašování. Pokud to povolí, tak je úspěšně přihlášen za pořád stejný účet.
Nenapadá Vás, co se v tom procesu může dít divného?
Je mozne hodit demo na Heroku? :-)