L1
Lampiran 1 Switch dan Router Wireless
L2
Lampiran 2 Komputer Server
L3
Lampiran 3 Ruang Kerja
L4
Lampiran 4 : Coding
Class pada Server.jar
Class Channel dari Server.jar : Public class channel { var int port; set voicePort; set reportPort; set UDP udp; public Channel { // mengambil nilai port sebagai nilai channel } public getPort{ } public void run() { try { set ServerSocket report (reportport) initiate Socket = null set udp (take port UDP); set ErrorHandling (socket); } } catch (Exception) { }
// memberi laporan pada overRUN
L5
} public void run() { set byte tempBuffer[] while (udp==tempBuffer) { synchronized (communications) { } } } } Class Container dari Server.jar :
public class Container { set Vector ports; public static String addChannel{
//membuat suatu string dengan mengambil nilai
channel. set int port = random(*25000+42000); baru if(ports==contains(port)) return addChannel(Container); else{ add port(port); start(new Channel(port)); return port; }
// melakukan random pada nilai port yang
L6
} } Class ErrorHandling dari Server.jar :
Public class ErrorHandling{ initiate UDP = null; initiate Socket = null; initiate PrintWriter; initiate BufferedReader; initiate String channel; initiate String name; initiate Channel c; initiate int port;
public ErrorHandling() { set c as channel; try { set socket as socket;
//mengeset socket
buffer as new BufferedReader(); set printwrite as new PrintWriter(socket); set name as "User0"; } catch (IOException) { } }
// set name default User
L7
// jika nama yang dipakai sama, maka account terakhir yang masuk dengan nama yang sama akan ditambahkan akhiran “+1” pada nama dengan account terakhir tersebut. private String assignName { String name; if (number > 1) { name = "Name" + number; } else { name = "Name"; } if (NameInUse) { return assignName(“number + 1”); } else { return name; } }
private boolean isNameInUse { for (i = 0; i < this.c.communications.size(); i++) { if (this.channel=c.communications.get (Channel)) && c.communications.name=(name)) { return true; } } return false;
L8
} //laporan dalam overRUN public void run() { handle (Data); } public void sendData() { print (data); } private void sendNewUserJoin { for (ErrorHandling = c.communications) { if (channel = this channel) { print(getName("newuser:");) } } } private void sendUserLeft { for (ErrorHandling = c.communications) { if (Channel = this Channel) { print ("userleft:" + getName()); } } }
private void nameChange() {
L9
if (name IS NOT in use) { for (ErrorHandling : c.communications) { if (channel = this channel) { print ("name:" + name + ":" + this.name); } } this.name = name; } else { print ("error:" + name + " is not correct "); } }
private void sendOnlineUsers { set String users = ""; for (ErrorHandling : c.communications) { if (channel = this channel) && name IS NOT in use) { users = ":" + u.name; } } if (users NOT empty) { sendData ("users" + users); } }
L10
private void startUDP { print("Server: starting udp"); set udp = (hostname, in, uit); try { Thread.sleep(value); } catch (InterruptedExceptio) { } udp.start(); }
private void handleData { set String msgReceived; try { while (message received in readLine() != null) { initiate String[tmp] = msgReceived.split(":");
if (tmp[0].equals("port")) { print(port reserved); port = Integer.parseInt(tmp[1]); startUDP(InetAddress.HostAddress,Port, this.port);
synchronized (communications) { communications.addElement(this); }
L11
}
if (tmp[0] equals “channel")) { set channel = tmp[1]; set name = name; sendOnlineUsers(); sendNewUserJoin(name); }
if (tmp[0] equals ”name”) { nameChange(trim); } } } catch (IOException ex) { try { print(socket + " has left the server"); synchronized (communications) { stop udp write; stop udp read; set udp=null; removeElement in communications; } close(buffer); close(printwrite);
L12
close(socket); send (UserLeft); stop(this); } catch (IOException) { printStackTrace(IOException); } } } public Socket getSocket() { return socket; } public String getChannel() { return channel; } public String getName() { return name; } }
L13
Class Udp dari Server.jar :
public class UDP extends Thread { initiate static DatagramSocket rs; initiate String ipa; initiate int inport; initiate int uitport; initiate static Read r; initiate Write w as new Write();
initiate int rport; initiate String rip; public UDP { set ipa = hostname; set inport = inport; set uitport = uitport; try { if (rs = null) { set rs as new DatagramSocket(inport); } if (r = null) { r = new Read(); r.start(); }
L14
w.start(); print("Server udp: reading / writing started"); } catch (Exception ex) { ex.printStackTrace(); } }
public UDP { ipa = hostname; try { rs = new DatagramSocket(); r = new Read(); r.start(); w.start(); this.uitport = port; } catch (Exception ex) { ex.printStackTrace(); } }
public static int getLocalPort(){ return rs.getLocalPort(); }
L15
public UDP(int port, boolean b) { try { if (rs == null) { rs = new DatagramSocket(port); } if (r == null) { r = new Read(); r.start(); } w.start();
} catch (Exception ex) { ex.printStackTrace(); } }
public class Write extends Thread { public void write(byte[] tempBuffer) { try { set DatagramPacket p as new DatagramPacket(); rs.send(p); } catch (Exception ex) { ex.printStackTrace(); }
L16
} } public class Read extends Thread { public boolean read { try { set DatagramPacket p as new DatagramPacket(); rs.receive(p); set rip as p.getAddress().getHostAddress(); set port as p.getPort(); set tempBuffer as p.getData(); } catch (IOException ex) { ex.printStackTrace(); } return true; } } }
Class Server pada Server.jar : public class Server { private static int voicePort = 45454; private static int reportPort = 55556;
public static void main {
L17
start(new Channel(45454)); } }
L18
Class pada client.jar
Class TCPConnectServer pada Client.jar :
public class TCPConnectServer extends Thread { initiate Socket verbinding; initiate PrintWriter printwrite; initiate BufferedReader buffer; initiate String history = ""; initiate Vector<String> friendlist = new Vector<String>(10);
public TCPConnectServer { set verbinding as s; try { set buffer as new BufferedReader(Inputstream); set printwrite as new PrintWriter(Outputstream); } catch (Exception) { e.printStackTrace(); } this.start(); }
// Laporan dalam overRUN public void run() {
L19
handle (Data); }
public void sendData() { print("To server: " + data); printwrite(data); }
private void handleData() { set String msgReceived; try { while ((msgReceived is in buffer.readLine != null) { print("From server: " + msgReceived); String[] tmp = msgReceived.split(":");
if (tmp[0] equal "newuser") { tmp[1] = trim(tmp[1]); add(friendlist as tmp[1]); print (history += getTimestamp() + tmp[1] + " joined the channel\r\n"); }
if(tmp[0] equal "users"){ for(i=1;i
L20
}
if (tmp[0] equal "name") {
tmp[1].trim(); tmp[2].trim();
for (int i = 0; i < friendlist.size(); i++) { if (friendlist equals tmp[2]) { friendlist.set(i, tmp[1]); } } Print( history += getTimestamp() + tmp[2] + " = " + tmp[1] + "\n"); }
if (tmp[0] equals "userleft") { tmp[1].trim(); friendlist.remove(tmp[1]); print (history += getTimestamp() + tmp[1] + " left the channel\r\n"); } } } catch (IOException ex) { ex.printStackTrace(); }
L21
} public String getTimestamp(){ initiate Date today as new Date(); initiate calendar as new Calendar(); initiate setTime calendar (today); initiate int h as calendar(Calendar.HOUR_OF_DAY); initiate int m as calendar(Calendar.MINUTE); initiate int s as calendar(Calendar.SECOND); return timestamp; //Di sini, waktu akan dicatat saat Client masuk ke Server } }
L22
Class UDPStream pada Client.jar :
public class UDPStream { initiate static DatagramSocket rs; initiate String ipa; initiate int inport; initiate int uitport; initiate Read r; initiate Write w as new Write();
public UDPStream() { set ipa as hostname; try { set rs as new DatagramSocket(); set r as new Read(); set uitport = port; } catch (Exception) { printStackTrace(); } }
public static int getLocalPort(){ return getLocalPort(rs); }
L23
public class Write extends Thread { public void write { try { set DatagramPacket p as new DatagramPacket(); send(rs as p); } catch (Exception) { printStackTrace(); } } } public class Read extends Thread { public boolean read { try { set p as new DatagramPacket(); rs.receive(p); tempBuffer = getData(p); } catch (IOException) { printStackTrace(); } return true; } } }
L24
Class Microphone pada Client.jar :
public class Microphone extends Thread implements Runnable { initiate BufferedInputStream input; initiate TargetDataLine targetDataLine; initiate BufferedOutputStream output; initiate AudioFormat audioFormat; initiate SourceDataLine sourceDataLine; initiate boolean transmit; initiate InputStream in; initiate OutputStream out; initiate UDPStream udp; initiate Thread captureThread; initiate Thread playThread; initiate static final int voiceactivation = 70; initiate static final int audiobuffer = 1024; initiate int voicemax;
public Microphone { set udp as new UDPStream(); udp.start();
set captureThread as new CaptureThread(); set playThread as new PlayThread();
L25
capture (Audio); this.start(); }
public void begin() { captureThread(); print("microphone thread started"); }
public void end() { udp.write(new byte[1024]); suspend(captureThread); print("microphone thread stopped"); } public void capture (Audio) { set audioFormat as get (AudioFormat); try { sourceDataLine.open(audioFormat); } catch (LineUnavailableException) { printStackTrace(); } sourceDataLine.start(); set input as new BufferedInputStream(in); set output as new BufferedOutputStream(out);
L26
try { Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo(); get (AudioFormat); set targetDataLine = null; set targetDataLine = (TargetDataLine) AudioSystem.getLine(info); target open dataline(audioFormat); start(targetDataLine); start(captureThread); suspend(captureThread); start(playThread); } catch (Exception) { printStackTrace(); } }
class CaptureThread { set byte tempBuffer[] = new byte[AUDIOBUFFER]; public void run() { try { nosound = false; while (true) { set int cnt as targetDataLine.read(tempBuffer, 0, tempBuffer.length);
//aktivasi suara nya
L27
set int voice as 0; for (int i = 0; i < tempBuffer.length; i++) { if (tempBuffer[i] >= (byte) voice | tempBuffer[i] <= (byte) (-1 * voice)) { voice++; } } if (voice > VOICEACTIVATION) { nosound=false; write udp (tempBuffer); } else { if(!nosound) { Write udp (new byte[1024]); set nosound=true; } } } } catch (Exception) { printStackTrace(); } } } class PlayThread extends Thread {
L28
byte tempBuffer[] = new byte[AUDIOBUFFER]; public void run() { try { while (read udp(tempBuffer)) { write sourceDataLine (tempBuffer, 0, AUDIOBUFFER); } } catch (Exception) { printStackTrace(); } } } private getAudioFormat(AudioFormat) { set float sampleRate; set int sampleSizeInBits; set int channels; set boolean signed = true; set boolean bigEndian = false; new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian); } }
L29
Class ImageButton pada Client.jar :
public class ImageButton{ public var normalImage:Image on replace { if(normalImage IS NOT null) { image = normalImage; } } set var disabledImage:Image = null; public var enabled = true on replace { if(disabledImage IS NOT null) { if(enabled) { set image = normalImage; } else { set image = disabledImage; } } opacity = 1; } public override var onMouseClicked = function(e:MouseEvent) { if(enabled) { opacity = 0.5; } } public override var onMouseExited = function(e:MouseEvent) { if(enabled) { opacity = 1; } } }
L31
Kelas main.fx pada VOIP client
package ahwapps; Menandakan bahwa main.fx ini berada pada package ahwapps.
import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.scene.Scene; import javafx.scene.text.Text; import javafx.scene.text.Font; import javafx.scene.control.ListView; import javafx.scene.control.Button; import javafx.scene.image.ImageView; import javafx.scene.*; import javafx.scene.image.*; import javafx.scene.paint.Color; Melakukan import yang diperlukan untuk merancang aplikasi ini. Pada fungsi dan library diatas dibutuhkan untuk merancang interfacenya.
import ahwapps.ImageButton; Perlu mengimport class Image Button yang dibuat pada package ahwapps. Class ini berfungsi untuk melancarkan dalam merancang interface ketika memakai fungsi image button.
L32
import ahwapps.TextArea; Kelas “TextArea.java” digunakan mensupport suatu text area pada interface agar bisa berjalan dengan baik sesuai yang diinginkan.
import suara.Microphone; import java.net.Socket; import javafx.scene.control.Label; import java.lang.Exception; Melakukan import class Java dengan nama “Microphone.java” yang berada pada package suara. Pada kelas ini berisi codingan yang dibutuhkan untuk mengaktifkan fungsi Micropone agar berjalan dengan baik. Serta fungsi untuk menerima hasil transimsi suara.
import jaringan.TCPConnectServer; import javafx.scene.control.TextBox; import javafx.animation.Timeline; import javafx.animation.KeyFrame; import javafx.scene.control.Slider; Pada bagian ini berfungsi mengimport kelas “TCPConnectiServer.java” yang berada diluar kelas “main.fx”, dan berada pada package jaringan. Selain itu, kelas ini juga berfungsi sebagai class yang menghubungkan dengan server.
import suara.UDPStream; import javafx.scene.image.Image;
L33
Berguna untuk mengimport kelas “UDPStream.java” yang berada pada package suara. Kelas ini juga berfungsi sebagai media kelas untuk bertukar komunikasi. Yang berupa pertukaran paket-paket data.
var channel:String = FX.getArgument("channel_id") as String; var serverip:String = FX.getArgument("server_ip") as String; membentuk suatu variabel masing-masing bernama channel dan serverip yang kemudian mengubah tipedatanya menjadi string. Sehingga bisa dibaca dan dideklarasikan.
var tcpverbinding: Socket; Membuat suatu socket dengan nama variabel yaitu tcpverbinding sebagai penampung socket.
var server: TCPConnectServer; Membuat variabel bernama server untuk menjalankan dan mengaktifkan kelas TCPConnectServer yang sudah dibuat dan sudah diimport.
var mic: Microphone; membuat variabel mic untuk menjalankan dan mengaktifkan kelas microphone yang tadi sudah diimport.
try { if (channel == null) set channel = "";
L34
if (serverip == null) set serverip = "";
set tcpverbinding as new Socket(serverip); mic = new Microphone(serverip, (set channel as int));
set server as new TCPConnectServer(tcpverbinding); set sendData to server("port: (getLocalPort)"); set sendData to server("channel:{channel}"); } catch (Exception) { println("getMessage()"); }
Potongan coding diatas adalah satu kesatuan yang berfungsi sebagai: Set channel sebagai “channel_id” (Nilai boleh random asal masih terdiri dari 5 digit dan dengan syarat semua user yang mau connect ke channel yang sama, harus menggantinya jadi nilai yang sama) Set ip server sebagai “server_ip” computer yang ingin dituju sebagai servernya (nilai server ip boleh diganti juga, tergantung kemana ip server yang dituju. Selain itu harus sesuai dengan pengaturan IP address computer) Set tcpverbinding untuk membuat suatu socket yang melakukan binding antara server ip dan port message pada server. Set mic berfungsi membuat baru dan memanggil fungsi microphone dan melakukan binding kepada serverip dan channel.
L35
Lalu variabel server yang akan membuat suatu fungsi pemanggil pada fungsi “TCPConnectServer (socket s)” yang isi “socket s” adalah tcpverbinding. Dan terakhir mengirim data informasi ke server berupa local port udp beserta channelnya.
Set friendlist as an Object[]; Initiate events as String; var poll: Timeline = Timeline { Timeline INDEFINITE keyFrames: [ KeyFrame { time: 1s action: function () { events = server.history; friendlist = server.friendlist.toArray(); mic.voice = 60 + voiceActivationSlider.value as Integer; } } ] } Potongan coding diatas berarti: set suatu variabel friendlist, berupa object. Membuat variabel events.
L36
Membuat variabel poll yang berisi time line yang akan muncul jika ada user masuk. Time line tersebut adalah sebagai history dan tidak bisa diubah atau dimanipulasi lewat user interface. Selain itu juga menampilkan kegiatan yang terekam dalam history server. Mengubah volume mic menjadi integer dan ditampilakan dengan dimulai dari tingkat atau indeks 60.
Kemudian kita mulai merancang antarmuka: Initiate var inputName: TextBox = TextBox Initiate var change= ImageButton Initiate var changeName: Button = Button Initiate var lbltitel: Label = Label Initiate var connectedList: ListView = ListView Initiate var lblConnected: Text = Text Initiate var eventsBox: TextArea = TextArea Initiate var lblEvents: Text = Text Initiate var btnActivate: Button = Button Initiate var voiceActivationSlider: Slider = Slider Initiate var voicelabel = Label Initiate var img1 = ImageView play(poll); Stage { title: "AHWapps VoIP Chat Client" scene: Scene { width: 438
L37
height: 664 content: [ img1, lbltitel, btnActivate, lblConnected, connectedList, lblEvents, inputName, changeName, change, voiceActivationSlider, voicelabel, eventsBox ] } resizable: false style: StageStyle.TRANSPARENT } }