AllJoyn - RgB project
Autor
Aliara
Letzte Aktualisierung
vor 9 Jahren
Lizenz
Creative Commons CC BY 4.0
Abstrakt
This is jut a college classwork.
This is jut a college classwork.
\documentclass[12pt]{article}
\usepackage[english]{babel}
\usepackage{longtable}
\usepackage[top=1in, bottom=1.25in, left=1.25in, right=1.25in,includefoot,heightrounded]{geometry}
\usepackage{indentfirst}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amssymb}
\usepackage{graphicx,tikz}
\usepackage{hyperref}
\usepackage[colorinlistoftodos]{todonotes}
\usepackage[document]{ragged2e}
\usepackage{fancyhdr}
\usepackage{enumerate}
\usepackage{listings}
\usepackage{color}
\usepackage{flowchart}
\usepackage{hyperref}
\usetikzlibrary{arrows}
\usetikzlibrary{shapes.geometric, arrows}
\tikzstyle{startstop} = [rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30]
\tikzstyle{decision} = [diamond, minimum width=4cm, minimum height=0.5cm, text centered, draw=black, fill=green!30]
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30]
\tikzstyle{arrow} = [thick,->,>=stealth]
\tikzstyle{io} = [trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=2cm, text width=4cm, minimum height=1cm, text centered, draw=black, fill=blue!30]
\pagestyle{fancy}
\fancyhf{}
\rhead{Aina Ferrà Marcús}
\lhead{RgB project}
\cfoot{\thepage}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\baselinestretch}{1.2}
\renewcommand{\labelitemi}{$\circ$}
\definecolor{MyDarkGreen}{rgb}{0.0,0.4,0.0} % This is the color used for comments
\lstloadlanguages{java} % Load C syntax for listings, for a list of other languages supported see: ftp://ftp.tex.ac.uk/tex-archive/macros/latex/contrib/listings/listings.pdf
\lstset{language=java,
%frame=single, Single frame around code
basicstyle=\small\ttfamily, % Use small true type font
keywordstyle=[1]\color{blue}\bf, % C functions bold and blue
keywordstyle=[2]\color{purple}, % C function arguments purple
keywordstyle=[3]\color{blue}\underbar, % Custom functions underlined and blue
identifierstyle=, % Nothing special about identifiers
commentstyle=\usefont{T1}{pcr}{m}{sl}\color{MyDarkGreen}\small, % Comments small dark green courier font
stringstyle=\color{purple}, % Strings are purple
showstringspaces=false, % Don't put marks in string spaces
tabsize=5, % 5 spaces per tab
%
% Put standard Perl functions not included in the default language here
morekeywords={rand},
%
% Put Perl function parameters here
morekeywords=[2]{on, off, interp},
%
% Put user defined functions here
morekeywords=[3]{test},
%
morecomment=[l][\color{blue}]{...}, % Line continuation (...) like blue comment
numbers=left, % Line numbers on left
firstnumber=1, % Line numbers start with line 1
numberstyle=\tiny\color{blue}, % Line numbers are blue and small
stepnumber=1 % Line numbers go in steps of 5
}
\lstset{literate=%
{à}{{\`a}}1
{é}{{\'e}}1
{è}{{\`e}}1
{í}{{\'i}}1
{ò}{{\`o}}1
{ó}{{\'o}}1
{ú}{{\'u}}1
{ç}{{\c{c}}}1
}
%\lstset{extendedchars=\true}
\lstset{inputencoding=ansinew}
\lstset{breaklines=true} %, postbreak=\raisebox{0ex}[0ex][0ex]{\ensuremath{\color{red}\hookrightarrow\space}}}
\begin{document}
\section*{AllJoyn documentation}
\subsection*{Classes implementades}
\begin{enumerate}
\item LocalNetworkService: conté els \textit{services} necessaris per crear la comunicació local.
\item LocalNetworkManager: hereta d'\textit{Application}. Controlador de l'aplicació. Es comunica amb els \textit{services} i les \textit{activities}.
\item Lobby i LobbyInterface: conté la informació necessària d'un lobby. Usem l'\textit{Interface} per la comunicació.
\item User i UserInterface: els usem per poder escoltar del bus.
\item UsersFacade: capa d'abstracció per poder cridar als mètodes sense haver de diferenciar entre \textit{client} o \textit{host} en la crida inicial.
\end{enumerate}
\subsection*{Disseny primari}
He decidit el següent per la implementació de classes de l'aplicació:
\begin{itemize}
\item L'activity inicial que comen+a la comunicació és la MultiPlayerActivity. Inicialitzarem els \textit{services} i el \textit{manager}. No ho fem abans en el joc perquè això és d'ús exclusiu del mode \textit{multiplayer} i no volem ocupar recursos innecessàriament.
\item Oferim dues opcions: CreateLobbyActivity, on podem crear un \textit{lobby} i esdevenir \textit{host}; JoinLobbyActivity, on ens podem unir a un \textit{lobby} ja creat i esdevenim \textit{client}.
\item Al JoinLobbyActivity ens apareixerà una llista de lobbies als quals l'usuari pot unir-se. Al tocar un dels noms dels lobbies, s'afegirà al mateix i anirà al CreateLobbyActivity. Aquest llistat es refresca de forma automàtica gràcies a un procediment que explicaré més tard.
\item Si algú s'uneix al CreateLobbyActivity des de MultiPlayerActivity, llavors és que està creant un \textit{lobby} i és \textit{host}. Guardem aquesta informació. Publicitarem el \textit{lobby} mitjançant els \textit{services} per a que altres dispositius el puguin trobar i ens quedarem a l'espera de que altres jugadors entrin.
Si un jugador entra des de JoinLobbyActivity, significa que és un \textit{client}. Guardarem el \textit{lobby} al qual vol entrar i esperarem a les accions del \textit{host}.
Un client pot abandonar la sala sense que passi res. Un \textit{host}, en canvi, provocarà que la resta de jugadors que estaven a la sala en surtin.
\end{itemize}
\subsection*{Qüestions tècniques sobre la comunicació}
En aquesta aplicació he pogut treballar amb dos tipus de comunicació:
\begin{enumerate}
\item Entre \textit{threads} del mateix dispositiu.
\item Entre diferents dispositius.
\end{enumerate}
\subsubsection*{Comunicació entre threads}
És important entendre que no podem comunicar-nos de forma normal, com habitualment estem acostumats amb els objectes, entre els \textit{threads}. Com que aquests funcionen en paral·lel, utilitzarem el que s'anomena \textit{Handlers}. Des d'un \textit{thread} podem enviar un missatge, que serà recollit per el \textit{handler} d'un altre \textit{thread} i tratarem adequadament. En el nostre cas en necessitem un pels \textit{Services} i un altre per les \textit{Activities}.
Tot això ho farem a través del LocalNetworkManager, que es qui ens fa de controlador (ja que hereta d'Application). Necessitarem que tingui un \textit{serviceHandler} i un \textit{activityHandler}, ja que necessitem accedir a aquests per enviar missatges. La comunicació, doncs, funciona de la següent manera (exposo dos exemples):
\begin{enumerate}
\item CreateLobby vol crear un \textit{lobby} i, per fer-ho, ens dóna el nom del lobby. Com que és el Manager qui porta un control de tots els lobbies que existeixen, per expert en la informació, és ell qui crearà el lobby. Ara bé, per poder-lo publicitar, ha d'enviar aquesta informació als \textit{Services}. Crea un missatge que identifiquem amb un int i l'envia, posant-li el lobby. El \textit{handler} dels \textit{services} recollirà aquest missatge i farà el que li toca (posar-lo al bus).
\item Quan trobem un objecte lobby, l'hem de posar a la llista de lobbies existents. Per això, els \textit{Services} li diuen al Manager que hem trobat un lobby i li dónen la seva \textit{Interface} corresponent (només podem treballar amb interfícies). El Manager s'ha de comunicar amb el JoinLobbyActivity per a que l'afegeixi a la seva ListView, així que crea un missatge i l'envia per el \textit{handler}.
\end{enumerate}
Veiem, doncs, que aquesta comunicació no afecta i no ens serveix per fer-ho entre dispositius.
\subsubsection*{Comunicació entre dispositius}
Ens basarem en el \textit{busObject} i les propietats que es dóna. Tanmateix, si mirem el framework de l'AllJoyn, veurem que només ens permet treballar amb interfícies i no amb objectes com a tal. Així, quan posem un objecte al bus, ha d'implementar una certa interfície que enregistrarem. Quan obtenim una informació del bus no ens retorna un objecte tampoc, cosa que dificulta el manteniment del que volem fer.
Per exemple, no podem tenir una llista de lobbies creats perquè no som capaços d'extreurer-los del bus. Hem de tenir una llista de lobbyInterface.
Dues coses a tenir en compte de l'aplicació:
\begin{enumerate}
\item El framework ens permet posar un \textit{Observer} que reacciona de forma automàtica quan es publicita un objecte que implementa una certa interfície.
\begin{lstlisting}
observer = new Observer(mBus, new Class[]{LobbyInterface.class});
observer.registerListener(new Observer.Listener() {
public void objectDiscovered(ProxyBusObject proxyBusObject) {}
public void objectLost(ProxyBusObject proxyBusObject) {}
});
\end{lstlisting}
Així, podem aconseguir capturar automàticament, a tots els dispositius, els lobbies que es creen i actualitzar el JoinLobbyActivity.
Aquest observer el creem quan registrem o el \textit{host} o el \textit{client} en el bus, ja que llavors comencem realment la comunicació. Hem de tenir en compte que no podem estar escoltant el bus i prou, hem d'enregistrar una interfície per fer-ho. Aquesta és la finalitat de l'User i l'UserInterface.
\item Veient com funciona la comunicació es presenta la pregunta: quin protocol de comunicació fem? Òbviament, necessitem un protocol \textit{client-servidor}. La nostra comunicació es basa en modificar la informació que aboquem sobre el Lobby. Per una part, el client usarà la interfície i per l'altra, el servidor pot llegir directament de l'objecte. Però això ens impedeix que el servidor envii missatges al client! La solució que he donat ha sigut fer un \textit{polling}. Veiem l'exemple de com refresco els usuaris que es troben a una sala:
\begin{itemize}
\item Al CreateLobby: demanem al Manager la llista d'usuaris de la sala.
\item Al Manager: demanem al UsersFacade la llista d'usuaris de la sala.
\item Al Facade: mirem si qui ho demana és host o no. Si és host, li demana al Lobby la llista d'usuaris de la sala. Si no és host, li demana a la interfície.
\item Ens retornen una llista d'Strings (UUIDs).
\item Al CreateLobby: imprimim correctament aquesta llista.
\end{itemize}
Amb aquest exemple espero demostrar la necessitat, al menys en primera instància, de fer un \textit{polling}, ja que si no disposo d'un objecte d'on agafar dades, no tinc cap manera d'enviar una ordre a la resta de dispositius i fer-los reaccionar, com sí que podia fer-ho amb l'Observer. De moment no he pogut trobar cap alternativa.
\end{enumerate}
\subsubsection*{Consideracions tècniques del bus}
\begin{enumerate}
\item Es pot llegir en el codi que per enregistrar i llevar un objecte del bus hi ha tot un procés tècnic al darrera. No cal explicar gaire el procés perquè és un estàndard que ens demana el framework. Sí cal, en canvi, pensar quan hem d'enregistrar l'objecte, quan l'hem de llevar del bus i quines accions extres hem de pendre.
\item A les \textit{Interface} hem de fer notar que les hem de passar per un bus, afegint: \lstinline{@BusInterface(name = "com.example.cantor.pruebamultiplayerv3.lobby", announced = "true")}. A més, els mètodes els hem de senyalar entre \lstinline{@BusProperty} (per getters i setters) i \lstinline{@BusMethod} (per la resta). En cas de dubte, usarem l'última anotació.
\item Hem de tenir en compte que només podem passar tipus primitius o un array de tipus primitius per el bus i que haurem d'especificar-ho a l'anotació, posant, per exemple \lstinline{@BusMethod(signature = "s")}. També podem fer un \lstinline{struct} i especificar cada atribut de quin tipus és i en quina posició es troba. Més informació sobre el tema:
\href{http://stackoverflow.com/questions/36815326/alljoyn-bussignalreply-error}{La meva pregunta respecte el tema a StackOverflow}
\href{http://stackoverflow.com/questions/18397088/signature-get-error-on-alljoyn-framework?lq=1}{Una pregunta respecte al tema d'estructures a StackOverflow}
\href{https://allseenalliance.org/docs/api/java/org/alljoyn/bus/annotation/Signature.html}{Documentació de l'AllJoyn}
\end{enumerate}
\end{document}