Java: IP telephony from scratch

    In the previous article, “Broadcasting Sound over a Network Using Java,” I described a method for receiving and broadcasting sound over a network using Java built-in tools.

    Here I will continue to develop this idea and tell you how to make a simple IP-telephony system using Java.

    The IP-telephony system consists of a server part that stores user credentials and their current IP, and a console client that is able to make and receive calls directly from the second subscriber.

    The full source code can be viewed on github .

    I ask everyone interested under cat.

    NetworkingAudioServer - server part of the system


    The server part is based on servlets, Apache Tomcat and MySQL.

    Database structure

    The database consists of two tables: users - stores user credentials and userinfo - maps each user IP and the time of its last update.

    CREATE TABLE IF NOT EXISTS `users` (
        `email` varchar(100) NOT NULL PRIMARY KEY, 
        `password` varchar(100) NOT NULL, 
        `confirm` varchar(100) NOT NULL,
        `user_id` varchar(100) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    


    The names email and password speak for themselves, confirm - the confirmation token of the email address or 'done' if the email is confirmed, user_id is the md5 hash from the email address (since it has a fixed length, it is convenient to use to identify an incoming call )

    CREATE TABLE IF NOT EXISTS `userinfo` (
        `email` varchar(100) NOT NULL PRIMARY KEY, 
        `user_id` varchar(100) NOT NULL, 
        `ip` varchar(100) NOT NULL, 
        `last_update` TIMESTAMP NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    


    The email and user_id fields correspond to the fields from the previous table, what ip is clear from the name, last_update is the time of the last IP update.

    Servlets

    RegisterServlet registers the user in the database and sends an e-mail request for confirmation using the following script:

    #!/bin/sh
    email=$1
    confirm=$2
    SERVER_URL="http://tabatsky.ru/networkingaudio";
    TMP_FILE="/common_scripts/tmp/$confirm";
    echo "To: $email" > $TMP_FILE;
    echo "From: service@tabatsky.ru" >> $TMP_FILE;
    echo "Subject: Networking Audio e-mail confirmation" >> $TMP_FILE;
    echo >> $TMP_FILE;
    echo "$SERVER_URL/confirm?confirm=$confirm" >> $TMP_FILE;
    echo >> $TMP_FILE;
    sendmail $email < $TMP_FILE
    


    ConfirmServlet - performs confirmation of e-mail.

    UpdateIPServlet - updates the client IP when requested, IP is determined automatically.

    GetUserInfoServlet - accepts email or user_id as a parameter ; upon request, returns email or user_id and current IP, or the value 'offline' if the IP has not been updated for more than three minutes.

    Server side setup

    To install the server side you need:
    • Create MySQL Database
    • Specify the correct login, password and MySQL database values ​​in the MyDBConnect class
    • Build and deploy on Tomcat
    • Specify the correct SERVER_URL value in the mail sending script, place the script itself at / common_scripts / sendConfirm and set the execution rights
    • Create a folder / common_scripts / tmp and set write permissions


    jNetworkingAudioClient - console client


    Customer structure

    The console client consists of four classes with program logic - Main , Master , Slave and IPUpdater , and two auxiliary classes - Util and DeclinedException .

    The Util class stores client settings — such as sound parameters and buffer size.

    The Main class is responsible for the programming logic of the interface.

    The IPUpdater class sends a request for an IP update to the servlet every 90 seconds.

    The Master class listens on the network port and, in turn, contains two nested stream classes: MicrophoneReader- reads data from the microphone and Sender - sends data to the second subscriber. Slave

    class : initiates a connection by sending an MD5 hash of an email address to the second subscriber, then, if the call is accepted, it starts reading data from the socket and sending it to the audio output. I’m probably not going to describe the client’s device in more detail - everyone can familiarize themselves with the source code.



    Client launch

    Here you can take a ready-made executable jar.

    Launch:

    java -jar jNetworkingAudioClient.jar http://serverUrl 2>log.txt
    


    Those interested can try on my server:

    java -jar jNetworkingAudioClient.jar http://tabatsky.ru/networkingaudio/ 2>log.txt
    


    But: in order to improve the server’s stability, I set a limit of 100 registered users.

    And the last: if you are sitting at a router, you need to redirect port 7373 to your car.

    UPD:


    There was a small problem - when I try to update my own IP through an external host, the servlet instead of my external IP gets the IP of my router on the internal network - 192.168.1.1.

    I came up with a small crutch - a trigger for MySQL:

    CREATE TRIGGER `my_host_ip` BEFORE INSERT ON `userinfo`
    FOR EACH ROW SET NEW.ip=IF(NEW.ip='192.168.1.1','tabatsky.ru',NEW.ip);
    

    Also popular now: