The command invocation protocol Lecture 14 The command invocation protocol
Generic Protocol We will learn about a generic protocol. Will allow clients to execute remote commands on the server. In previous lectures we have seen:
The protocol A command is sent by a client but executed by the server (on the server process). A class that “packages” a function and arguments. The server may pass a single argument to the command. This argument can hold different services that the command can interract with.
Generic Command Invocation: Life Cycle At Client: Command object is instantiated Command object is serialized into a byte[] int length of byte[] is sent to server (4 bytes) byte[] is sent to server At Server: Data is received at server, byte by byte First 4 bytes are converted to int int size is read and stored in byte[] byte[] is deserialized back into Command object Command object is executed – function returns object Object is serialized into byte[] – this is the response byte[] sent back to client
Java Serialization/De-Serialization
RemoteCommandInvocationProtocol
Java Serialization Object serialization: an object can be represented as a sequence of bytes. This sequence includes the object's data and type, and the types of data stored in the object. A serialized object (i.e., a byte[]) can be deserialized back into a copy of the original object. The byte[] that represent the object and its data can be used to recreate the object in memory. The process is JVM independent.
Java Serialization Classes ObjectInputStream and ObjectOutputStream can serialize and deserialize any Serializable object. A class is Serializable if it: Implements the Serializable interface or it super class is Serializable. Its first non-serializable super class has a no-args constructor. All its non-transient fields must be serializable. Serializable has no methods or fields. In principle – any data can be serialized.
Java Serialization: Example class Person implements java.io.Serializable { public transient int age; public String name; public Example(int age, String name){ this.age = age; this.name = name; } } To make a class serializable, all needs to be done is to implement: Class <ClassName> implements Serializable{ … } Java will handle the rest! Note: transient will exclude age from the serialization process!
ObjectOutputStream: Example import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.Date; public class Main { public static void main(String[] args) throws Exception{ FileOutputStream fos = new FileOutputStream(“file_name"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeInt(12345); oos.writeObject("today"); oos.writeObject(new Date()); oos.close(); } }
ObjectInputStream: Example import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.Date; public class Main { public static void main(String[] args) throws Exception{ FileInputStream fis = new FileInputStream("file_name"); ObjectInputStream ois = new ObjectInputStream(fis); int i = ois.readInt(); String today = (String) ois.readObject(); Date date = (Date) ois.readObject(); ois.close(); } }
Message Encoder Decoder (previous lecture)
Message Encoder Decoder for arbitrary objects Previously we saw an implementation for String. The ObjectEncoderDecoder is a binary encoder decoder. An Object will be serialized into Byte array: N,b1,b2,b3,...,bn N - the message will start with the number of bytes. Sent in binary representation (methods intToByte(), byteToInt()).
A generic client for our generic protocol
Example: NewsFeedServer This server will allow clients to execute two commands: Publish news to a (TV) channel by its name Fetch all the news which were published to a specific (TV) channel The main object that is manipulated by the server is the NewsFeed: Command will execute this!
The client commands receive the NewsFeed and manipulate it
NewsFeed implementation Since the news feed can be manipulated concurrently by different handlers in the server it must be thread safe.
A method of ConcurrentHashMap: computeIfAbsent(key, mappingFunction) if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) map.put(key, newValue); } This is done once per news channel. After its invocation, the specific channel will have an entry in the hashmap, so the consequent executions will have no effect – since not absent!
The server main (thread-per-client…)
The client main
The client code will print: second client received: [System Programmer, knowledge in C++, Java and Python required. call 0x134693F] third client received: [new SPL assignment is out soon!!, THE CAKE IS A LIE!]