-
Notifications
You must be signed in to change notification settings - Fork 6
Implement your own Shark ASAP application (2 of 5)
This steps brings your application closer to be a decentralized ASAP application. We are going to design (not yet implement) algorithms. There are actually two sets of algorithms to be implemented. It might look a bit outlandish first. It will be very simple in retrospect, though. Promised.
Most algorithms will be very small and require just a few lines of code. Also promised. Take you time in this step. You have it.
- 2.1 - Recall ASAP
- 2.2 - The Big Picture
- 2.3 - Choose ASAP format
- 2.4 - Implement API methods
- 2.5 - Handle Received Messages
- Results
First step: Make yourself familiar with ASAP, if you have not done that yet: What is ASAP and read section ASAP Peer. Go ahead with 2.2 afterwards.
Welcome back. A core element of your ASAP application will be an ASAP peer. Most applications have to deal with two general incidents:
- App users interact with your application.
- Your application (with a ASAP peer in it) encounters another one.
That is the most essential difference between centralized and decentralized applications. Let’s assume a centralized messenger app: User Alice types something in her app (client side). A send action delivers serialized data to the central server. Applications logic runs on server side which informs other client applications. Another client side retrieves data from the server and presents it after de-serialization to its user, e.g. Bob.
A decentralized messenger is (slightly) different: User Alice also types something in her app. No difference. Your ASAPApp stores those data locally, though. That is different. Data exchange is made during a peer encounter. (This can be in ad-hoc networks. An encounter can also happen via Internet, see e.g. ASAPHub. ASAP applications are not more slowly by design! They are free to chose their infrastructure by design, though – a slow or fast one. But we do not have to deal with those details yet).
We have to deal with to sets of algorithms:
- How to implement your API? What happens if a user interacts with your application.
- What has to be done during a peer encounter?
You do not have to write down much in this step. You do not have to implement anything. Take your use cases. Take some paper, a pencil and a tea (or whatever makes you relaxed) and think it over. Play out the scenarios.
Let's take our messenger as an example and use case: "send a message". What happens? User Alice interacts with your API and enters a message. What would you do with it? It must be stored with the ASAP peer. That’s right. But become more specific and remember ASAP message structure.
Make a (mental) note here. What is next. Well, actually nothing. Nothing would happen if there is no other peer nearby.
What happens if there is a peer encounter. Both peers exchange messages. Algorithms are required that deal with incoming messages. Messages can be ignored, can be presented to users. Messages can be re-sent or not.
There are two sets of algorithms: One has to deal with user interactions on your applications. What of your application data are to be sent to other peers. How would ASAP messages look like.
The other set has to deal with received messages. How can you extract you application data from messages? Are messages to be re-sent to other peers?
Make a sketch, get the big picture. That is the task of this step. The algorithms have to be described in detail in the next steps.
Some other thoughts: ASAP can be compared to oral communication. Think in that way. Alice says something (to Bob). What would Alice (have to) do if she hears a message? You could describe even more complex scenarios like a kind of digital money. Alice issues a bond to Bob. Alice remembers that fact - in IT terms: Alice peer is in a status that remembers the fact of an issued bond. Bob receives a message that contains a bond of Alice. What to do with it? Maybe he decides to sign and sends it back. Alice receives a signed bond from Bob issued by here. What would she do? Etc. pp. Think your application as a series of messages. Your application can remember sent messages. Your application must not expect a reply (in a given time frame). Your application is free to ignore a message that does not return within an expected time frame, though. Your application must not stop working.
It is probably the most complicated step on the whole trail. Think of your whole app. Gosh. Take your time. It can be fun.
It would be no surprise if you would change your API in the process. Do it. You have not yet implemented anything. Changing interfaces does not do any harm in this stage of development. Later it will.
But as always: No over-engineering. Stop it if your thoughts start circling. Start the next step and become more specific. You can come back here anytime. Most will which is ok and normal.
Thanks to the previous steps, you have a fairly good idea what method call results in sending an ASAP message. Some questions remain. The most crucial one is: How many applications are you about to build?.
You might answer: One of course. What a stupid question. Maybe it is but not in any case.
A messenger application often has two facets: Message exchange but also exchange of contact information. Both parts are clearly separated and have different goals: One is to learn about people and addresses. The other exchanges messages. I looks like two different ASAP apps with different format which run together in your application.
Read section Message structure (again).
Choosing a format or multiple formats has some impact on your software design. Implement clearly different tasks as own modules. Treat them as different ASAP applications and give each its own format.
You could also think of mail boxes. You are about implementing a distributed application. Your are about implementing code. Instances of the same code are going to run on different machines. Your instances will communicate by message exchange only. The format helps to separate incoming messages. Code becomes less complex. Choose different formats if you identify separated tasks in your application. If not – there is just one.
It is now time to start coding. Add your format(s)
public interface YourApplicationAPI {
String APP_FORMAT = “yourOrganisationName/yourAppFormatName”;
// your methods follow here e.g.
void method1(String parameter);
void method2(String parameter);
void method3(String parameter);
}
Your are ready to start implementing your API.
public class YourApplicationAPIImplementation implements YourApplicationAPI {
private ASAPPeer peer; // assume it is there - we come back to this point
void method1(String parameter) {/*TODO*/}
void method2(String parameter) {/*TODO*/}
void method3(String parameter) {/*TODO*/}
}
You are, of course familiar with concepts like facade and delegate and we do not discuss those software engineering things here but only ASAP specifics.
Now, go through your API and decide for any method: Does any call of this method require a data transfer to another peer? Games often have an initialization phase. Play stones are set up. In chess, there is no communication required because the initial setup is clearly defined. It is the same with games like battleship – the initial setup has to remain a secret to the other party.
From an ASAP point of view, there are two relevant method types: a) Methods which require sending information and b) methods which require received data.
Let's discuss a) first and come back to our previous example. That would be an implementation.
void sendMessage(Message message) {
// need to send a message
// 1st: serialize it:
MessageSerializer serializer = new MessageSerializer(
message.getRecipient(),
message.getMessage));
byte[] serializedMessage = serializer.getSerializedMessage();
// define a uri if you like
String uri = "yourChat://chatRoomA";
// 2nd: send it with ASAP peer
this.peer.sendASAPMessage(APP_FORMAT, uri, serializedMessage);
}
}
peer.sendASAPMessage(..) keeps this message with the peer. This message is transmitted whenever possible during an encounter. It is the better choice in most cases.
There is an alternative method: peer.sendOnlineASAPMessage(..) would send this ASAP message only to peers which are connected right now. This message is neither stored nor will their be any other attempt to re-transmit this message.
You might need to encrypt or sign your messages. Read section Cryptography in our developer guide. There is a full Public Key Infrastructure (PKI) Component. The PKI is based on ASAP and can run as a parallel Shark Component in your application.
Peers store messages and make at least one delivery attempt to any other peer. This default behaviour can be changed, read section behaviour management in our develoder guide.
Most application want to present received data. A messenger application does barely anything else. We need access to received messages. There are two general ways:
- You program your own data management. You add received messages to your persistent storage and implement methods to receive them.
- ASAP peers store both kinds of messages - sent and received. Read section ASAPStorage for details. This option is a good choice for any messenger like application. Our PKI has also no own persistency management.
Choice is yours. You should seriously consider using ASAPStorage. Con: You have to learn this little API. Pro: There is no other parallel persistent data management. You do not have to implement it.
Nearly any application is interested in receiving messages. It is time to remember section receive message. You have to register a listener for any supported format. This is a good thing. It helps to clarify your code. It also helps to separate your code from other components.
There is not much else to explain. There are no further hidden tricks and hints. You must general choice is already made: Do you have your own data management or do you use ASAPStorage instead, see previous section.
Congratulations. You have (started) implementing your API. That is very good. Because there are only two remaining steps: Test your software and implement a user interface. There is one intermediary step, though. It can be skipped but we strongly suggest to make your application a Shark Component. It takes less than an hour but allows your application to become part of a larger one. It is worth the time. Next step - make it a component.