Chat WebSocket server
Chat WebSocket server slouží pro implementaci chatu v prostředí webu přes WebSocket protokol. Tento server udržuje seznam připojených klientů, který mohou každý s každým prostřednictvím serveru komunikovat.
Ihned po připojení klienta k serveru zašle server klientovi první textovou zprávu, která obsahuje ID tohoto připojeného klienta. Na tuto zprávu musí klient odpovědět s vlastní identifikaci klienta, která je následně ze serveru odesílaná spolu s ID všem ostatním připojeným klientům. Vždy když se k serveru připojí nový klient, nebo se od serveru některý stávající klient odpojí, odešle server všem klientům zprávu obsahující seznam klientů aktuálně připojených k serveru.
Průběh komunikace
- Klient se připojí k serveru
- Server odesílá zprávu s klientovým ID
- Klient odesílá zprávu s klientskou identifikací
- Server odesílá všem klientům zprávu INFO se seznamem všech klientů
- Klienti mohou mezi sebou libovolně komunikovat pomocí MESSAGE zpráv
Po připojení klienta k serveru, server odešle klientovy zprávu obsahující ID daného klienta. Pomocí tohoto ID si následně mohou klienti mezi sebou posílat zprávy. Zpráva s ID klienta vypadá například takto:
65
Na zprávu s ID klienta následně klient musí odpovědět zprávou se svojí identifikaci. To může být jakákoliv textová zpráva, která obsahuje informace o klientovi, které jsou následně rozesílané ve zprávě s informacemi o připojených klientech. Zpráva s identifikací klienta může vypadat například takto:
{
"givenClientId":"65",
"name":"John Smith"
}
Následně server rozešle všem klientům nový seznam připojených klientů ve zprávě typů INFO. Tato zpráva může připojenému klientovi dorazit kdykoliv během připojení k serveru. Zpráva INFO může vypadat například takto:
{
"type":"INFO",
"clients":[
{
"id":65,
"identification":"{\"givenClientId\":\"65\",\"name\":\"John Smith\"}"
},
{
"id":38,
"identification":"{\"givenClientId\":\"38\",\"name\":\"Inge Levis\"}"
}
]
}
Poté již může klient zasílat zprávy libovolnému klientovi podle jeho ID. Například klient s ID 65 odešle zprávu klientovi s ID 38 takto:
{
"type":"MESSAGE",
"to":"38",
"data":"Hello message from 65 to 38."
}
Klientovi 38 pak tato zpráva ze serveru dorazí takto:
{
"type":"MESSAGE",
"from":"65",
"data":"Hello message from 65 to 38."
}
Příklad Chat WebSocket serveru
V příkladu níže se tři klienti připojí k WebSocket Chat serveru a mohou si mezi sebou posílát zprávy pomocí jednoduchých formulářů.
<form>
<input type="text" value="Chat msg from 1" id="chatInput1">
<select id="chatTo1">
<option value="1">To client 1</option>
<option value="2">To client 2</option>
<option value="3">To client 3</option>
</select>
<input type="submit" value="Send" id="chatBtn1">
<div id="chatOutput1"></div>
<input type="text" value="Chat msg from 2" id="chatInput2">
<select id="chatTo2">
<option value="1">To client 1</option>
<option value="2">To client 2</option>
<option value="3">To client 3</option>
</select>
<input type="submit" value="Send" id="chatBtn2">
<div id="chatOutput2"></div>
<input type="text" value="Chat msg from 3" id="chatInput3">
<select id="chatTo3">
<option value="1">To client 1</option>
<option value="2">To client 2</option>
<option value="3">To client 3</option>
</select>
<input type="submit" value="Send" id="chatBtn3">
<div id="chatOutput3"></div>
</form>
<script>
var ws = [null, null, null];
var wsClientData = [null, null, null];
var processMessage = function (event, clientItt) {
if (wsClientData[clientItt] === null) {
wsClientData[clientItt] = {
givenClientId: event.data,
name: "Web Socket " + (clientItt + 1)
};
ws[clientItt].send(JSON.stringify(wsClientData[clientItt]));
} else {
var message = JSON.parse(event.data);
if (message.type == "INFO") {
document.getElementById('chatTo' + (clientItt + 1)).innerHTML = "";
for (var i = 0; i < message.clients.length; i++) {
message.clients[i].identification = JSON.parse(message.clients[i].identification);
document.getElementById('chatTo' + (clientItt + 1)).innerHTML += "<option value=\"" + message.clients[i].id + "\">" + message.clients[i].identification.name + "</option>";
}
}
if (message.type == "MESSAGE") {
document.getElementById('chatOutput' + (clientItt + 1)).innerHTML += message.data + "<br>";
}
}
};
var processClosing = function (event, clientItt) {
console.log(event.code);
console.log(event.reason);
};
var sendMessage = function (event, clientItt) {
var message = document.getElementById('chatInput' + (clientItt + 1)).value;
messageData = {
type: "MESSAGE",
to: document.getElementById('chatTo' + (clientItt + 1)).value,
data: message
};
ws[clientItt].send(JSON.stringify(messageData));
event.preventDefault();
return false;
};
ws[0] = new WebSocket('ADRESA_MEHO_CHAT_WEESKA');
ws[0].addEventListener('message', function (event) {
processMessage(event, 0);
});
ws[0].addEventListener('close', function (event) {
processClosing(event, 0);
});
document.getElementById('chatBtn1').addEventListener('click', function (event) {
return sendMessage(event, 0);
});
ws[1] = new WebSocket('ADRESA_MEHO_CHAT_WEESKA');
ws[1].addEventListener('message', function (event) {
processMessage(event, 1);
});
ws[1].addEventListener('close', function (event) {
processClosing(event, 1);
});
document.getElementById('chatBtn2').addEventListener('click', function (event) {
return sendMessage(event, 1);
});
ws[2] = new WebSocket('ADRESA_MEHO_CHAT_WEESKA');
ws[2].addEventListener('message', function (event) {
processMessage(event, 2);
});
ws[2].addEventListener('close', function (event) {
processClosing(event, 2);
});
document.getElementById('chatBtn3').addEventListener('click', function (event) {
return sendMessage(event, 2);
});
</script>