Uvod u WebSocket-e
WebSocket predstavlja protokol koji je razvijen kao deo HTML5 inicijative, kako bi se definisao JavaScript interfejs, kojim bi se omogućila perzistentna veza izmeću klijentske Web stranice i servera preko jednog soketa, gde se poruke mogu razmenjivati u oba smera u svakom trenutku (full duplex bidirectional communication over a single TCP connection).
Perzistentna veza znači da je veza otvorena i nakon razmene prve poruke. Kao što znamo, HTTP protokol funkcioniše na principu pitanja i odgovora, gde klijent pošalje zahtev serveru za podacima, a server odgovara u vidu podataka klijentu, nakon čega se veza zatvara. Za svako pitanje-odgovor potrebna je jedna TCP veza.
Web soketi nam omogućavaju da razmenjujemo podatke sa serverom preko jedne TCP veze. I to ne samo jednu poruku, već koliko god želimo, gde nam server može poslati podatke kada kod želi, bez eksplicitne potrebne da ih klijent zatraži. Ovo predstavlja glavnu benefit Web soketa, jer preko jedne veze možemo razmenjivati više poruka, dok nam server može slati podatke kada god želi, bez ikakvih ograničenja.
WebSocket JavaScript klijent - DEMO
Napravite folder sa nazivom Chat-App. U okviru tog foldera, napravite još dva foldera: css i js. Takođe napravite i fajl index.html
.
U folderu css smestite bootstrap.min.css
fajl. Takođe napravite fajl style.css
.
U folderu js napravite fajl app.js. U tom fajlu pisaćemo sav JavaScript kod. Takođe napravite folder lib, i u njega smestite bootstrap.min.js
fajl, kao i jqery.min.js
fajl.
Klijent je implementiran uz korišćenje JavaScript jezika, uz pomoć biblioteka Jquery. Za skroman izgled stranice je korišćen Bootstrap.
Kod index.html
stranice:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Chat app</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/lib/jquery-1.11.3.min.js"></script>
<script src="js/lib/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<h1><span class="label label-default">Chat</span></h1>
<form class="form-group">
<div class="form-control" id="chatResponses"></div>
<div class="row">
<div class="col-md-2">
<input class="form-control input-lg" id="name" type="text">
</div>
<div class="col-md-10">
<input class="form-control input-lg" id="chatInput" type="text">
</div>
</div>
</form>
</div>
</div>
</div>
</body>
<script src="js/app.js"></script>
</html>
U head delu referenciramo sve potrebne biblioteke. Samu aplikaciju referenciramo na dnu stranice, ispod body dela. Stranica sadrži deo za prikaz poruka od svih klijenata, deo za unos nadimka, kao i deo za unos teksta za slanje.
Kod style.css
fajla:
#chatResponses {
max-width: 100%;
height: 300px;
border: 1px solid #ccc;
padding: 5px;
overflow: auto;
overflow-x: hidden;
text-wrap: normal;
margin-bottom: 10px;
}
p {
font-family: Verdana, Geneva, sans-serif;
font-size: 14px;
font-style: normal;
font-variant: normal;
font-weight: 400;
line-height: 20px;
}
Da biste koristili WebSocket-e, potrebno je inicijalizovati promenljivu korišćenjem WebSocket konstruktora, koji kao ulazni parametar prima url endpointa koji se nalazi na serveru. U fajl app.js
, napišite sledeću liniju koda:
var socket = new WebSocket('ws://localhost:8080/chat-server/chat');
URL endpointa počinje sa ws, koji označava WebSocket protokol. Postoji mogućnost slanja preko sigurno konekcije, i u tom slučaju bi prefiks bio wss. WebSocket protokol predstavlja apstrakciju nad HTTP protokolom.
Nakon oznake protokola sledi adresa i port servera, i na kraju, tačna adresa WebSocket endpointa na pomenutom serveru.
Nad promenljivom socket moramo da implementiramo određene metode koje su nam neophodne za rad sa WebSocket-ima (onOpen
, onClose
, onError
, onMessage
). Ove metode kao ulazni argument primaju neki event, koji se u okviru metode obrađuje.
OnOpen metoda
Ako se pri kreiranju soketa uz pomoć konstruktora WebSocket(‘url’)
uspešno uspostavi konekcija, izvršiće se ova metoda.
socket.onopen = function open (e) {
console.log('Veza sa serverom je uspesno uspostavljena: WebSocket Open event');
};
OnClose metoda
Pri zatvaranju konekcije između klijenta i servera, izvršiće se ova metoda.
socket.onclose = function close (e) {
console.log('Veza sa chat serverom je prekinuta: WebSocket Close event');
};
OnError metoda
Ukoliko dođe do neke greške u konekciji, izvršiće se ova metoda.
socket.onerror = function error(e) {
console.log('Doslo je do greske: WebSocket Error event');
};
OnMessage metoda
Kada stigne poruka sa servera, izvršiće se ova metoda.
socket.onmessage = function message (e) {
var data = JSON.parse(e.data);
var node = document.createElement("P");
var text = document.createTextNode(data.name + ' | ' + data.chatText);
node.appendChild(text);
document.getElementById("chatResponses").appendChild(node);
};
U ovom primeru, poruke koje će dobijati klijent od servera su u JSON formatu i sadrže nadimak klijenta i tekst koji je klijent otkucao.
Primer ulaza:
{
name: "PETAR",
chatText: "Hello World!!! "
};
Kako se ulaz preko eventa e dobija u tekstualnom formatu, potrebno ga je konvertovati u JSON objekat metodom JSON.parse()
. Svim informacije koje se šalju putem WebSocket-a se nalaze u e.data
promenljivoj.
Zatim, kreiramo node element (HTML <p></p>
tag), kao i text element (tekst koji ćemo smestiti u okviru node elementa). Text element smeštamo u okviru node elementa metodomappendChild()
. Takođe, istom metodom dodajemo node element div elementu na index.html
stranici koji ima id=”chatResponses“
.
Slanje podataka putem WebSocket-a
U ovoj demo aplikaciji, korisnik u input polje koje ima id=”name”
unosi svoj nadimak. Takođe, u okviru input polja koje ima id=”chatInput”
unosi tekst koji želi da pošalje. Pritiskom na taster Enter
, uneto ime i tekst poruke se pretvaraju u JSON objekat i šalju na server putem metode send()
.
$("#chatInput").keyup(function (e) {
if (e.keyCode == 13) {
var nickname = document.getElementById("name").value;
if(nickname == "" || nickname == null) {
alert('Unesi ime!');
return;
}
var text = document.getElementById("chatInput").value;
if (text == "" || text == " " || text == null){
return;
}
var jsonData = {
name: nickname,
chatText: text
};
socket.send(JSON.stringify(jsonData));
document.getElementById("chatInput").value = "";
}
});
Korišćenjem Jquery biblioteke, dohvatamo element sa index.html
stranice koji ima id=”chatInput”
, i nad njim pozivamo metodu keyup, koja reaguje na svako pritiskanje tastera. Ako je šifra tastera jednaka broju 13, to znači da je korisnik pritisnuo Enter
na svom računaru.
U promenljivoj nickname
ćemo smestiti nadimak klijenta, ako ga je uneo. Ako nadimak nije unet, ispisaće se upozorenje o grešci. Ako je input polje za unos teksta prazno, izvršavanje metode će se prekinuti.
Kada su uneti i nadimak i tekst, smeštaju se u okviru JSON objekta sa nazivom jsonData.
Kako bismo poslali na server taj JSON objekat, potrebno je da nad soketom pozovemo metodu send()
i prosledimo joj taj JSON objekat u vidu teksta (uz pomoć metode JSON.stringify()
). Nakon slanja podataka na server, brišemo tekst iz polja za unos teksta.
Napomena:
Pomoću send()
metode možemo slati tri tipa podatak:
- Text (UTF)
- BLOB
- ArrayBuffer
To takođe znači da možemo i prihvatiti onMessage()
ove tipove podataka. Da bismo mogli da svaki tip obradimo na odgovarajući način, potrebno je da proverimo koji tip podatak nam je stigao putem WebSocket-a.
Načini za proveru:
e.data instanceof ArrayBuffer
e.data instanceof Blob
typeof e.data === "string"
Korisni linkovi: