% !TEX root = main.tex

\subsection{Nettverkslag}

\subsubsection{Valg av transportlag}

For å gjøre det mulig å bruke webapplikasjonenen til å styre roboten over
	internett måtte det velges en egnet teknologi.
Styring over \emph{internett} begrenser oppgaven i praksis til IP-basert
	(Internet Protocol) kommunikasjon.
Fordi det var ønskelig å kunne kommunisere fra en webapplikasjon/nettleser, var
	valgmulighetene videre begrenset.
Nettlesere i dag støtter JavaScript, som gjør det mulig å programmere oppførselen
	til nettsiden, samt diverse plugins for multimedia og mer avansert
	programvare.

Forskjellige plugins er tilgjengelige til nettlesere for å kommunisere over
	nettverk.
Så godt som alle nettlesere har Flash installert.
Flash støtter både TCP og UDP.
Java er også et annet alternativ der man kan benytte både TCP og UDP.

Dersom man ikke ønsker å bruke en nettleser-plugin, finnes det to andre valg.
Begge disse kan aksesseres gjennom JavaScript:

\begin{description}
\item[HTTP-forespørsler]
	innebærer at klienten må initiere alle overføringer\cite{RFCHTTP}.
	Denne funksjonaliteten er innebygget i nettleseren sin
		JavaScript-funksjonalitet, men er mer egnet for å hente data fra en
		nettside, og ikke en robot.
	For roboten var det ønskelig å kontinuerlig motta siste tilstand fra roboten
		slik at dette kan vises.
	Dersom klienten hele tiden må sende HTTP-forespørsler (polling), blir dette
		tungt.
	Fordelen med HTTP-forespørsler er at trafikken slipper gjennom de aller
		fleste proxyer og brannmurer, fordi den er lik vanlig nettsidesurfing.
\end{description}

Et eksempel på HTTP er vist i figure \ref{fig:HTTP-eksempel}.

\begin{figure}[H]
	\begin{verbatim}
		GET /index.html HTTP/1.1
		Host: www.example.com
	\end{verbatim}
	\caption{Eksempel på HTTP}
	\label{fig:HTTP-eksempel}
\end{figure}

\begin{description}
\item[WebSockets]\cite{RFCWebSocket} tilbyr toveis kommunikasjon, og bygger på
	TCP.
Opprettelsen av en WebSocket likner på en HTTP-forespørsel, men tilkoblingen
	blir ikke lukket når forespørselen er over.
Tilkoblingen fortsetter å være åpen, og klient og server kan utveksle meldinger
	(frames).
WebSockets ser ut som HTTP-forespørsler, og kan slippe gjennom brannmurer, men
	ikke alle proxyer.
WebSockets er standardisert av IETF, og er støttet av alle de populære
	nettleserne.
\end{description}

Å bruke HTTP-forespørsler ville innebære enten å tilpasse en eksisterende
	server, eller å skrive vår server fra grunnen av.
En slik server vil være mer omfattende enn en WebSocket-server.
HTTP i seg selv tilfører ikke noe nyttig funksjonalitet utover det å være
	tilgjengelig overalt, så valget falt på WebSockets.

Opprettelsen av en WebSocket består av følgende type forespørsel fra klienten:
\begin{Verbatim}
        GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: WebSocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Origin: http://example.com
        Sec-WebSocket-Protocol: chat, superchat
        Sec-WebSocket-Version: 13
\end{Verbatim}

Deretter følger toveis utveksling av \emph{frames}, der hvert frame består av en
	header etterfulgt av data som skal overføres.
Innholdet i disse defineres av applikasjonslaget.


\subsubsection{Valg av applikasjonslag}

For enkelhets skyld ble det valgt å opprette to toveis forbindelser mellom hver
	klient og serveren.
Den ene forbindelsen brukes til styring av roboten, der man kan sende kommandoer
	og motta responsen på kommandoene (styringsforbindelse).
Den andre forbindelsen (tilstandsforbindelse) vil serveren kontinuerlig strømme
	informasjon om robotarmens tilstand, slik at klienten kan oppdatere
	visningen sin.
Å gjøre dette i to forskjellige forbindelser gjør implementasjonen enklere, og
	det er naturlig fordi det er to vidt forskjellige typer trafikk.

Tilstandsforbindelsen blir kun brukt i én retning, fra server til klient.
Det ble også sett på som fordelaktig å formatere data som JavaScript Object
	Notation (JSON), ettersom dette er enkelt å dekode i JavaScript på klienten,
	og det er tilgjengelig i Qt-rammeverket.

Et eksempel på JSON-formatert data sendt fra server til klient er vist i figur
	\ref{fig:json-server-client}.
Dataen som er vist er representert som et JSON array med tre objekter der hvert
	av objektene representerer en servomotor.
Servomotorene inneholder en id og en tilstand.
For servomotorene ble det hentet ut to tilstander: vinkel og hvorvidt motoren
	var i bevegelsesmodus eller ikke.

\begin{figure}[H]
	\begin{Verbatim}
		 [
		     {
		         "id": 1,
		         "state": {
		             "angle": -42.1875,
		             "is_moving": false
		         }
		     },
		     {
		         "id": 2,
		         "state": {
		             "angle": 24.66796875,
		             "is_moving": false
		         }
		     },
		     {
		         "id": 3,
		         "state": {
		             "angle": -0.29296875,
		             "is_moving": false
		         }
		     }
		 ]
	\end{Verbatim}
	\caption{Eksempel på JSON-formatert data sendt fra server til klient}
	\label{fig:json-server-client}
\end{figure}

For styringsforbindelsen var det ønskelig å tilby APIet til robot-driveren, som
	består av en rekke funksjoner.
Nettverkslaget burde være så tynt som mulig, og tilby dette APIet til klienten
	(over internett).
Det var derfor naturlig å gjøre det i form av RPC (Remote Procedure Calls).

Det vil si at klienten (i JavaScript) kan kalle \method{setAngle}{45, 3} for å
	sette vinklen på servo med id 3, til 45 grader.
Informasjonen om dette kallet ('setAngle') og dets parametere (3, 45) overføres
	over WebSocket, og på mottakersiden tolkes det og utføres på serveren.
Eventuell returverdi for prosedyrekallet sendes så tilbake.
Det finnes flere RPC-standarder, blant annet JSON-RPC\cite{SpecJSONRPC} og
	SOAP\cite{SpecSOAP}.
I JSON-RPC og SOAP formateres informasjonen om prosedyrekallet og parameterne
	som henholdsvis JSON eller XML.
JSON er kompakt og godt støttet i både JavaScript og C++, mens SOAP er mer
	kompleks og dermed vanskeligere å implementere.
På grunnlag av dette ble JSON-RPC valgt.

Et eksempel på et JSON-RPC-kall og respons fra \method{setAngle}{45, 3} er vist
	under.
\verb|-->| indikerer data sendt fra klient til server, og \verb|<--| er det
	motsatte.

\begin{Verbatim}
--> {"jsonrpc": "2.0", "method": "setAngle", "params": [45, 3], "id": 1}
<-- {"jsonrpc": "2.0", "result": 0, "id": 1}
\end{Verbatim}

JSON-RPC støtter også notifications, som er kall uten returverdi.
Kallet vil da ikke inkludere et \verb|``i''|-felt.


\subsubsection{Implementasjon av nettverkslag}
Fordi robot-driveren var skrevet i C++/Qt, var det naturlig å skrive serveren i
	noe kompatibelt.
Alternativene som ble vurderte var QtWebsocket (C++/Qt)\cite{QtWebSocket},
	WebSocket++ (C++/Boost)\cite{WebSocketpp} og libWebSockets
	(C)\cite{libWebSockets}.

Det ble avgjort at QtWebSockets tilbød ønsket funksjonalitet, og kom med flere
	eksempler - både for servere og klienter.
QtWebsocket tilbyr klassene \class{QWsServer} og \class{QWsSocket}.
En \class{QWsServer} kan instanseres og bli bedt om å lytte på en gitt IP-adresse og
	port.

For å implementere JSON-RPC fantes flere muligheter; oppe til vurdering var
	JsonRpc-Cpp\cite{jsonrpccpp} og QJsonRpc\cite{qjsonrpc}.
Førstnevnte er minimal og burde være enkel å bruke.
Ulempen er at den bruker et tredjeparts Json-bibliotek.
qjsonrpc er en Qt-basert implementasjon, som baserer seg på \class{QTCPServer}
	og \class{QTCPSocket} fra Qt.
Det er mer komplekst enn JsonRpc-Cpp, men fordi det er bygget på Qt, er det
	lettere å integrere med en Qt-applikasjon.

QJsonRpc-biblioteket tilbyr fra før en \class{QJsonRpcTcpServer}-klasse.
Denne benytter en \class{QTCPServer}, og tillater flere TCP-tilkoblinger.
For å støtte WebSockets ble det valgt å utvide biblioteket med en ny klasse,
	QJsonRpcWebSocketServer som benytter \class{QWsServer} i stedet for
	\class{QTCPServer}.
For å gjøre dette mulig, måtte \class{QWsSocket} endres for å oppføre seg mer
	som en \class{QTCPSocket}.
Dette innebar å alltid emittere signalet \method{readyRead}{} når et
	WebSocket-frame er mottatt, og å implementere \method{readData}{} og
	\method{writeData}{} som kan sende og motta WebSocket-frames.
En \class{QJsonRpcWebSocketServer} instansieres i fila \file{main.cpp}.

For tilstandsforbindelsen ble Qt sine funksjoner benyttet for JSON-formatering
	sammen med \class{QWsServer}.
Denne er implementert i klassen \class{Server}, som instansieres i fila
	\file{main.cpp}.

\subsubsection{Implementasjon for web-klient}
Web-klienten utvikles i JavaScript.
WebSockets er tilgjengelig gjennom \method{WebSocket}{}-konstruktøren
	\cite{writingWebSocket}, og dette APIet er implementert i alle de mest
	brukte nettleserne Internet Explorer, Firefox, Chrome, Safari og
	Opera\cite{Awio2014}\cite{statcounter2014}.
Det er derfor ikke nødvendig å anskaffe et eget bibliotek for WebSockets.

Denne implementasjonen ble bygget videre på, og innkapslet i klassen \class{Ws}.
Denne tilbyr mer funksjonalitet for debugging av WebSockets, som å logge
	nettverkstrafikken, og skrive informasjon til konsoll når tilstanden til en
	WebSocket endrer seg.
Denne klassen er til dels basert på eksempelkode inkludert i QtWebSocket.

JSON-RPC-funksjonalitet oppnås ved hjelp av et tredjepartsbibliotek kalt jQuery
	JsonRpcClient\cite{jsonrpcclient}, som bygger på det populære
	jQuery-rammeverket.
