[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r21079 - gnunet-java/doc
From: |
gnunet |
Subject: |
[GNUnet-SVN] r21079 - gnunet-java/doc |
Date: |
Sun, 22 Apr 2012 22:16:47 +0200 |
Author: dold
Date: 2012-04-22 22:16:47 +0200 (Sun, 22 Apr 2012)
New Revision: 21079
Modified:
gnunet-java/doc/gnunet-java-tutorial.tex
Log:
draft of the tutorial updated
Modified: gnunet-java/doc/gnunet-java-tutorial.tex
===================================================================
--- gnunet-java/doc/gnunet-java-tutorial.tex 2012-04-22 20:13:48 UTC (rev
21078)
+++ gnunet-java/doc/gnunet-java-tutorial.tex 2012-04-22 20:16:47 UTC (rev
21079)
@@ -29,27 +29,29 @@
\subsection{Installing gnunet}
This tutorial assumes that you have gnunet$\geq$0.9.2 installed on your
system. Instructions on how to do this can be found at
\url{https://gnunet.org/installation}.
Make sure that you run {\tt configure} with the option {\tt
--enable-javaports}.
-Start gnunet with the command {\tt gnunet-arm -s}. Convince yourself that the
default gnunet services are running by typing {\tt gnunet-arm -I}.
+Start gnunet with the command {\tt gnunet-arm -s} and convince yourself that
the default gnunet services are running by typing {\tt gnunet-arm -I}.
\subsection{Installing gnunet-java}
Check out the latest version of gnunet-java with subversion: \\*
{\tt svn checkout https://gnunet.org/svn/gnunet-java/} \\*
Tools for gnunet-java development are located in {\tt tools/}, while the {\tt
bin/} directory contains
-shell wrappers for java programs using gnunet. Now run the command
+shell wrappers for java programs interfacing with gnunet. Now run the command
{\tt ./tools/build} to compile {\tt gnunet-java}.
To test whether your gnunet-java installation is working, try to run the
"gnunet-nse" program (in {\tt bin},
-which should display the current estimated size of the network.
+which should display the current estimated size of the network).
-Throughout the tutorial it will be useful to consult the javadocs for
gnunet-java, either built them yourself with {\tt ./tools/make-javadoc} or use
the online version at \url{https://gnunet.org/javadoc/}
+Throughout the tutorial it will be useful to consult the javadocs for
gnunet-java,
+either built them yourself with \\* {\tt ./tools/make-javadoc}
+or use the online version at \url{https://gnunet.org/javadoc/}
\section{Creating an extension}
Check out the template directory for gnunet-java extensions with the following
command: \\*
{\tt svn checkout https://gnunet.org/svn/gnunet-java-ext/ }
-Now edit the file envcfg.sh. This file contains the necessary information so
that scripts in the
-gnunet-java-ext/tools directory, as well as the shell-wrappers in
gnunet-java-ext/bin can find your gnunet-java installation. Not that the
template directory already contains an example extension that will print a
"hello world" message, we will ignore this in the next section and write our
own.
+Now edit {\tt envcfg}. This file contains the necessary information so that
scripts in the
+{\tt gnunet-java-ext/tools directory}, as well as the shell-wrappers in {\tt
gnunet-java-ext/bin} can find your gnunet-java installation. Not that the
template directory already contains an executable example extension that will
print a "hello world" message, you should ignore this and write your own.
\section{A simple gnunet-java program}
@@ -65,9 +67,8 @@
}
\end{lstlisting}
-The Program class takes care of parsing command line arguments (thus it's
constructur gets the args array passed)
-and loading the gnunet configuration files (accessed by
Program.getConfiguration())
-(talk about scheduler/asynchronous stuff)
+Calling {\tt start} initializes gnunet-java, parses the command line, loads
configuration files and
+starts the task scheduler, with the code in the {\tt run} method as initial
task.
{\bf Exercise:} Try to get the code above running. Place your code in the {\tt
src/} directory (so that you can use the build script in {\tt tools}, copy and
modify the example shell-wrapper {\tt bin/gnunet-ext} until you can
run your own program with it.
@@ -99,20 +100,25 @@
Inside of the run-method, the class member 'name' will then be initialized
with the passed argument,
or null if the option has not been passed.
-The address@hidden annotation can not only be used with Strings, but also with
booleans and numbers. The following types of actions are available:
+The address@hidden annotation can not only be used with Strings, but also with
booleans and numbers. These are a few
+of the available options:
\begin{itemize}
\item {\tt STORE\_STRING}: Store a string in a {\tt String} variable
+\item {\tt STORE\_NUMBER}: Store a number in a member of primitive type
+\item {\tt SET}: Set a boolean to true
\end{itemize}
By default, the following arguments are available on the command line:
\begin{itemize}
\item {\tt -h} / {\tt --help} shows the help text
\item {\tt -v} / {\tt --version} shows version information
-\item {\tt -}
+\item {\tt -c} / {\tt --config} specify an additional configuration file to
load
+\item {\tt -L} / {\tt --log} specify the log level
+\item {\tt -l} / {\tt --logfile} specify a file to write the logs to
\end{itemize}
-You can change the about text and the version by subclassing the getVersion /
getAboutTest methods in your Program subclass.
+You can change the about text and the version information by subclassing the
getVersion / getAboutTest methods in your Program subclass.
-\subsection{Using an existing service API}
+\section{The statistics API}
In this section we will use the statistics-API of gnunet-java. This service
allows us to store numbers under a subsystem and a name, which are still
available to you and other components of your peer if your program quits.
\subsubsection{Establishing a connection with the statistics service}
@@ -145,7 +151,8 @@
\begin{lstlisting}[language=java]
// the name parameter is the empty string, this gets all options of the
specified subsystem
-Cancelable getCancel = statistics.get(RelativeTime.SECOND,
"gnunet-java-hello", "", new Statistics.StatisticsReceiver {
+Cancelable getCancel = statistics.get(RelativeTime.SECOND,
"gnunet-java-hello", "",
+new Statistics.StatisticsReceiver {
public void onDone() {
System.out.println("everything done");
}
@@ -159,80 +166,102 @@
\end{lstlisting}
-{\bf Exercise:} Write a program that takes a name from the command line. Greet
that name, and count / print out how many times your program has greeted
somebody before. {\it Tip:} You can use the gnunet-statistics command line
program to view and
+{\bf Exercise:} Write a program that takes a name from the command line. Greet
that name, and count / print out how many times your program has greeted
somebody before. {\it Tip:} You can use the {\tt gnunet-statistics} command
line program to view and
modify values from the statistics service.
\bigskip
-\section {Overview of useful APIs}
-statistics
+\section{The core API}
+The core API allows sending messages to other connected peers.
-dht
-* explain dht-put and dht-get / one example
-
-core
-* explain API, maybe refer to example code
-
-
-\section{Creating a new gnunet-java service}
-
\subsection{Defining new Messages}
-All gnunet services have a common communication protocol.
-Every message consists of a header (with the message size and the message
type), and a body.
+All gnunet messages follow a common communication protocol.
+Every message consists of a header (with the message size and the message
type) and a body.
-You can define a new type of Message in gnunet-java by annotating a class with
how
-to represent its members in binary format.
+You can define a new type of nessage in gnunet-java by annotating a class with
how to represent its members in binary format.
-Additionaly, you have to register your new message type with gnunet-java,
giving it a unique id.
-
+Additionaly, you have to register your new message type with gnunet-java,
giving it a unique id. Here's an example:
\begin{lstlisting}
@UnionCase(4242)
-public class HelloWorldMessage implements GnunetMessage.Body {
+public class ExampleMessage implements GnunetMessage.Body {
@UInt8
public int age;
@ZeroTerminatedString;
public String name;
}
\end{lstlisting}
-Todo: explain the above
+The {\tt @UnionCase} annotation specifies the message id of the message body
below. That is, GnunetMessage.Body
+actually is a union of messages, and ExampleMessage just one member of the
union.
-Other useful annotations are:
-...
+Every time you add a new type of gnunet message, you have to run the {\tt
tools/update-msgtypes} command. This
+generates the file {\tt src/org/gnunet/construct/MsgMap.txt}, which allows the
system to load the right
+java class when reading a message from the network.
+Other useful annotations can be found in the package {\tt
org.gnunet.construct}. Among them are annotations for
+zero-terminated strings ({\tt @ZeroTerminatedString}), arrays of fixed or
variable size
+({\tt @VariableSizeArray, @FixedSizeArray}), for embeding other messages in
your message ({\tt @NestedMessage} and
+for implementing your own message unions.
-Running the msgtypes-tool:
+\subsection{Connecting to Core}
+After creating a handle to core by calling the {\tt Core} constructor, you
have to specify what
+types of messages you are interested in. The core service will only send
messages of these types to you,
+and only notify you of connecting peers if they share a subset of the messages
you are interested in.
-\subsection{Implementing the Service}
-Similarily to Program.run, Service.run is the entry point of every gnunet-java
service.
-It's members can be annotated with the same command line parsing options as in
Program.
+The {\tt handleMessages} method allows you to specify an object of a class
inheriting {\tt Runabout}.
+The Runabout is a mechanism for single-argument multiple dispatch in Java.
+You have to define one {\tt visit} method for every type of message you are
interested in.
+Once Core receives a Message, it is dispatched dynamically to the visit method
with the right signature.
+Note that every visit method, as well as the receiver's class has to be
public, in order for the
+dynamic dispatch to work.
-The first difference is that every Service has at least one server, waiting on
new clients to connect.
-When implementing a Service, you have to specify the kind of messages you are
interested in.
+Example:
+\begin{lstlisting}
+public class MyMessageReceiver extends Runabout {
+ public visit(MyFooMessage m) { /* do something */ }
+ public visit(MyBarMessage m { /* do something else */ }
+}
+\end{lstlisting}
-The basic skeleton for a Service looks like this:
+After specifing your message handler, the {\tt init} method has to be called
with a callback object.
+This starts the handshake with the core service, once done the callback
object's {\tt onInit} method will
+be called with your peer's identity.
-\subsubsection{Talking back to a client}
-explain Client.this.notifyTransmitReady(...)
+\subsection{Sending a message}
+Before you can actually send a message, you have to wait until core is ready
to receive a new message.
+This is done by calling the {\tt notifyTransmitReady}. You have to provide a
callback object to this method,
+whose {\tt transmit} method is invoked with a {\tt MessageSink} object once
the core is ready to transmit your message.
+Call the {\tt send} method in the {\tt MessageSink} in order to finally
transmit it.
-\subsection{Creating the configuration file}
-For every service ther is a configuration file that specifies
-over which port the service is reachable. Other options in the configuration
can be used to
-configure the service without touching the code or implementing your own
configuration.
+Example:
+\begin{lstlisting}
+// arguments: messagePriority, timeout, targetPeer, messageSize, transmitter
+client.notifyTransmitReady(0, RelativeTime.FOREVER, myIdentity, new
MessageTransmitter() {
+ public transmit(Connection.MessageSink sink) {
+ sink.transmit(myMessage);
+ }
+ public onError() {
+ // do something
+ }
+\end{lstlisting}
-[provide example config file here]
-\subsection{Using arm to start the service}
+{\bf Exercise:} Write a program that connects to core, and send a message to
the local peer!
-\section{Communicating with a Service directly}
-\subsection{Using the client API}
-\subsubsection{Creating a new Client}
-\begin{lstlisting}
-Client = new Client("hello-world-service", getConfiguration());
-\end{lstlisting}
-establishes a connection with the service named "hello-world-service". The
necessary information (e.g. the right TCP/IP port) for connecting
-to the service is is looked up under the section [hello-world-service] in the
configuration.
+\section{Other useful APIs}
+Many of gnunet's services are not yet available as a gnunet-java API.
+The other two service APIs currently implemented are nse (in {\tt
org.gnunet.java.nse.NetworkSizeEstimation}),
+a service that gives an estimation of the current size of the network, and dht
(in {\tt org.gnunet.java.dht.DistributedHashTable}), a service that allows
key/value pairs to be stored distributed across the network.
+\section{Writing your own client/server}
+{\tt gnunet} is split up in components, every component runs in its own
process.
+In the previous sections you have used existing APIs to interface with other
services.
+gnunet-java also provides the tools necessary to directly interface with
services yourself.
+The {\tt org.gnunet.util.Client} class allows to connect to a gnunet service
and transmit/receive messages.
+\section{The state of gnunet-java}
+The {\tt gnunet-java} project is under heavy development, expect changes that
break your stuff!
+Please send any suggestions, questions or complaints to {\tt address@hidden
+
\end{document}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r21079 - gnunet-java/doc,
gnunet <=