Wednesday, December 30, 2015

Free Basics In India

For the past few days, I have found myself in the midst of a raging argument between Facebook's  'Free Basics' solution in India and violation of 'Net Neutraility' principles by 'Free Basics'. But do we really understand what does net neutrality mean? A simple definition of net neutrality is that each and every resource on the internet should be treated equally and should be accessible to everyone irrespective of it's origin. Agreed.


The next big question is does 'Free Basics' really violate the definition of net neutrality? If we look at the face value of what 'Free Basics' actually is, then yes, it is actually violating the principles of net neutrality. For those who are unaware of what 'Free Basics' actually is, it provides internet access free of cost to the people who don't have access to the internet  by partnering with a telecommunication provider at a cost that only some of the websites which are registered with 'Free Basics' are accessible. Some of the websites  range from the health, entertainment category to news and public information category. Currently not all the websites are on 'Free Basics'. If you need a list of the websites that are currently included in 'Free Basics' for India, you can find the list in this link. I do agree that considering the above definition, 'Free Basics' does violate the principles of net neutrality. It might turn out to be an unfair competition for the internet businesses which are not registered on 'Free Basics' with the one that are. I agree to this point whole heartedly, that's why I see people on Facebook, Twitter and other social networking sites opposing the implementation of 'Free Basics' in India. I respect their point of view.


But my question is, are we asking the right questions? Is it only about net neutrality? Isn't it about making internet accessible to the rural villages in India? It's very unfortunate to see that people are openly opposing 'Free Basics' and blasting them on the internet, but has anyone of us thought about bringing internet access to the villages, which actually was the primary problem in the first place? We are currently in the 21st century, and around 4.4 billion people in the world don't have access to internet. India contributes around quarter of that offline population. Has anyone thought about how to get them connected? Sadly, no. The sad fact is everyone is up taking sides either with 'Save the Internet' or 'Free Basics'. But has anyone thought of taking sides with the people who are actually living in the dark ages of information? It's time we should think.


'Save the Internet' is putting in a huge effort in order to stop 'Free Basics' from being implemented in India. Their motto is that the whole internet should be accessible to everyone. Again, agreed. I appreciate their effort. But let's say, the solution is not implemented in India, do they have a solution up their sleeve where they will make the internet accessible to the villages? I haven't seen any effort from them in this direction. Just because of the fact that we don't have a solution, we won't let anyone else solve the problem because we find that the competition would be unfair among the businesses. According to me, this perspective is totally uncalled for.


So does it mean, that we should blindly accept the solution provided by Facebook? The answer is no. I agree to 'SaveTheInternet' 's point that regulations should be in place to check net neutrality. It's time we have laws which protects the  interests of the consumers. But also, we need to understand the bigger picture. 'Free Basics' is actually for the greater good of the people. But yes, this solution also needs to be kept under check and should be regulated. For that, laws have to be in place.


If you still don't agree with 'Free Basics' then it's time we come up with a solution which trumps 'Free Basics'. We can't keep other people in the dark just because we don't have a solution at hand.


I do support 'Free Basics' because it's for the greater good but having said that, I support it conditionally. If not, we need to come up with a solution in which we provide internet access to the people but also protect the neutrailty of the internet. If such a solution comes along, I will be more than happy to support it.


It's time we also think of our people instead of blindly supporting 'Free Basics' or 'Net Neutrality'.  

Friday, December 4, 2015

Websocket Server and Client in Java


In this post we are going to develop a simple Websocket Server and Client in Java. Before writing code for server and client, we first need to add the following dependencies in pom.xml, if it's Maven project, otherwise you can download these jars manually and add it to your project dependency.


 <dependencies>
  <dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-server</artifactId>
    <version>1.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-client</artifactId>
    <version>1.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-container-grizzly</artifactId>
    <version>1.1</version>
</dependency>
</dependencies>


The above dependencies have a tyrus-server, tyrus-client and a tyrus-container for the server to run.


Now we will be creating the server end point class called TestServerEndPoint -

import java.io.IOException;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.*;

@ServerEndpoint(value="/testServerEndPoint")
public class TestServerEndpoint {
   
    @OnOpen
    public void onOpen(Session session) {
    System.out.println("Session opened with session Id "+session.getId());
    }
   
    @OnMessage
    public void onMessage(String message, Session session) {
    System.out.println("Received message: "+message+" from session Id "+session.getId());
    try {
    session.getBasicRemote().sendText(message);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
   
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
    System.out.println("Closed session "+session.getId());
    }
   
   

}



This is the server end point of we socket. The @ServerEndpoint denotes that this class is going to act as the server end point. The value in the ServerEndpoint annotation will be used in the URL while connecting to the server. We have over ridden three methods in this class -
1) The onOpen method will be called whenever a client establishes a session with the server. Each session will be assigned an Id. We are printing out that Id, whenever a client connects to our server.
2) The onMessage method will be called whenever a client sends in a message to the server. We are printing that message along with the ID of the session sending that message. The server is then sending back the same message to the client.
3) The onClose method will be called whenever a client closes the session. We are printing out the session ID of the session being closed.

We will be creating a runnable class for the server called Test Server -

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.websocket.DeploymentException;

import org.glassfish.tyrus.server.Server;

public class TestServer {
   
    public static void main(String[] args) {
    Server testServer = new Server("localhost", 8025, "/testServer", TestServerEndpoint.class);
    try {
    testServer.start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Please press a key to stop the server.");
    reader.readLine();
    testServer.stop();
    } catch (DeploymentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
   
    }

}


In the main method we are creating an instance of Server class. The TestServer will be running on port 8025 with TestServerEndpoint as it's server end point. The "/testServer" will be used in the URL when the client will be connecting to the server. We then call testServer.start() to start the server. When you run the above class, the server should start successfully -


Dec 04, 2015 11:22:23 PM org.glassfish.tyrus.server.ServerContainerFactory create
INFO: Provider class loaded: org.glassfish.tyrus.container.grizzly.GrizzlyEngine
Dec 04, 2015 11:22:24 PM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [0.0.0.0:8025]
Dec 04, 2015 11:22:24 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Dec 04, 2015 11:22:24 PM org.glassfish.tyrus.server.Server start
INFO: WebSocket Registered apps: URLs all start with ws://localhost:8025
Dec 04, 2015 11:22:24 PM org.glassfish.tyrus.server.Server start
INFO: WebSocket server started.
Please press a key to stop the server.



Now we will be creating a client which will be connecting to our server. First we will be creating an end point for the client similar to the end point of the server -


import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;

@ClientEndpoint
public class TestClientEndpoint {
   
    @OnOpen
    public void onOpen(Session session) {
      
    }
   
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("Received message from server "+message);
    }
   
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
      
    }
   
   

}


We have created an end point for client called TestClientEndpoint. The methods over ridden are the same as the methods over ridden in the TestServerEndpoint. In the onMessage method, we are printing out the message received from the server.

Now we will be creating the client.

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.websocket.DeploymentException;
import javax.websocket.Session;

import org.glassfish.tyrus.client.ClientManager;

public class TestClient {
   
    public static void main(String[] args) {
        ClientManager client = ClientManager.createClient();
        try {
            Session clientSession = client.connectToServer(TestClientEndpoint.class, new URI("ws://localhost:8025/testServer/testServerEndPoint"));
            clientSession.getBasicRemote().sendText("Hello! How are you?");
            Thread.sleep(5000);
            clientSession.close();
        } catch (DeploymentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
 

We have created an instance of client. In the URL we are using
"ws://localhost:8025/testServer/testServerEndPoint"
ws denotes a websocket connection between the client and the server.
localhost:8025 denotes we are connecting to the server locally at port 8025.
/testServer is the server instance as mentioned in our TestServer class.
/testServerEndpoint is the server end point as mentioned in our TestServerEndpoint class.

In the main method we are creating an instance of client and then we are using the client instance to connect to the server. On connecting to the server, a session is getting generated and then we are using the session to send a message to the server. We are finally closing the session. The Thread.sleep(5000) is introduced in order to give some time to the client to receive the message from the server.

Console output of Server -
Dec 05, 2015 12:04:46 AM org.glassfish.tyrus.server.ServerContainerFactory create
INFO: Provider class loaded: org.glassfish.tyrus.container.grizzly.GrizzlyEngine
Dec 05, 2015 12:04:47 AM org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [0.0.0.0:8025]
Dec 05, 2015 12:04:47 AM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Dec 05, 2015 12:04:47 AM org.glassfish.tyrus.server.Server start
INFO: WebSocket Registered apps: URLs all start with ws://localhost:8025
Dec 05, 2015 12:04:47 AM org.glassfish.tyrus.server.Server start
INFO: WebSocket server started.
Please press a key to stop the server.Session opened with session Id e993682e-d5ca-428c-8267-88022abfea1d
Received message: Hello! How are you? from session Id e993682e-d5ca-428c-8267-88022abfea1d
Closed session e993682e-d5ca-428c-8267-88022abfea1d


 We can see from the console of the server that a session was created by the client. And then it received a message from the client "Hello! How are you?" and finally the session was closed.

Console output of Client-
Received message from server Hello! How are you?

In the console output of the client, we can see the message received from the server.

Congrats!!! You have successfully created a websocket server and a client. If you face any issues, please mention your issue in the comments below, and I will try to reply to it as soon as I can. Till then, enjoy coding. :-P

Sunday, November 15, 2015

Media Player API using vlcj

About vlcj
The vlcj API provides a Java framework to allow an instance of native vlc media player to be embedded in a Java AWT window or a Swing frame. Basically if you want to create a media player in AWT or Swing, you can use vlcj API to develop your own media player. However the requirement for using this API is to have VLC player installed in your system, so that it can use it's libraries.

MediaPlayer API
The mediaplayer API uses vlcj internally and also provides swing controls such as a pause button (play button), a stop button and a video slider. It's very easy to use for developers who don't want to re invent the wheel of again writing the code for  adding basic Swing components (media player options) to their media player. You just add a single line of code and you are done. For instance -

new MediaPlayer("/home/reets/Videos/TestVideo.mp4", "/usr/bin/vlc/").launchMediaPlayer();

This will launch a media player and will play your media file passed to it as an argument. I will explain what are the constructors and publicly available methods for this API.

Constructors-

1) new MediaPlayer( 'Location of your Media File', 'Location of your VLC Player Installation')

This constructor takes two parameters -
a) The location of your media file to be played as a String
b) The location of your VLC player installation as a String

For example -
new MediaPlayer("/home/reets/Videos/TestVideo.mp4", "/usr/bin/vlc/");

2) new MediaPlayer('File object of your Media File', 'Location of your VLC Player Installation')

This constructor takes two parameters-
a) The file object of your media file to be played
b) The location of your VLC player installation as a String

For example -
File mediaFile = new File("/home/reets/Videos/TestVideo.mp4");
new MediaPlayer(mediaFile, "/usr/bin/vlc/");

3) new MediaFile('Input Stream of the media file to be played','Location of your VLC Player Installation')

This constructor takes two parameters-
a) The input stream of the media file to be played as an InputStream
b) The location of your VLC player installation as a String

For example-

try {
            InputStream inputStream = new FileInputStream(new File("/home/reets/Videos/TestVideo.mp4"));
            new MediaPlayer(inputStream, "/usr/bin/vlc/");
        } catch (FileNotFoundException e) {
                       e.printStackTrace();
        }


How to launch the media player-

In order to launch the video player you will just have to call the method 'LaunchMediaPlayer()' and that's it, you are done!!!

new MediaPlayer(inputStream, "/usr/bin/vlc/").launchMediaPlayer();

This single line of code will launch your media player and play the video you want it to play.



Word of Caution-
You need to have VLC player installed in order to use this API since internally it uses VLC libraries. Generally the default installation paths for VLC player are -

For Linux - '/usr/bin/vlc'
For Windows - 'C:/Program Files (x86)/VideoLAN/VLC/'

Download-
https://www.dropbox.com/s/b95vyceixe9k30a/MediaPlayerApi-1.0.jar?dl=0

The source code will be released shortly. The API will be constantly updated with features. Your comments are most welcome so that I can update the API with the necessary features. If you face any problem while using this API please post your problem in the comment section. I will try to resolve it as soon as I can.