Fungsi push pesan yang diselesaikan oleh WebSocket dan Java digunakan oleh server tomcat7.0. Beberapa hal dipertimbangkan sendiri, dan saya tidak tahu apakah itu tepat atau tidak pantas. Mohon maafkan saya dan tunjukkan mereka.
Secara sederhana, pelanggan A dapat mengirim pesan ke pelanggan B, tetapi ada banyak tempat yang dapat diperluas.
Misalnya
1. Jika setelah bergabung dengan database, ketika mengirim pesan, pelanggan B tidak online, server akan menyimpan pesan dalam database. Setelah Pelanggan B online, pesan tersebut akan diambil dan dikirim ke Pelanggan B.
2. Server juga dapat mengirim pesan ke klien mana pun.
Tangkapan layar dari efek berjalan program adalah sebagai berikut (diuji di bawah Chrome, Sogou, dan Firefox): Kode akan diberikan pada akhirnya
Pertama, kami membuka browser dan menampilkan untuk memasukkan nama Anda. Di sini saya memasuki Soar
Saat membuka browser kedua, di sini saya memasuki tagihan
Ini jika saya mengirim tagihan halo saya melambung ke tagihan, klik kirim
Anda dapat melihatnya di browser lain
Websocket
1. Apa itu Websocket?
WebSocket adalah teknologi yang dihasilkan untuk memecahkan komunikasi real-time antara klien dan server. Esensi adalah membuat koneksi TCP untuk bertukar data setelah penanganan melalui protokol HTTP/HTTPS.
Setelah itu, server dan klien berkomunikasi secara real time melalui koneksi TCP ini.
2. Keuntungan Websocket
Di masa lalu, kami menerapkan teknologi push, menggunakan polling. Pada interval waktu karakteristik, browser secara otomatis mengeluarkan permintaan dan secara aktif menarik kembali pesan server. Dalam hal ini, kita perlu secara konstan mengirim permintaan ke server. Namun, header permintaan HTTP sangat panjang, dan data yang terkandung di dalamnya mungkin hanya nilai kecil, yang akan menempati banyak sumber daya bandwidth dan server. Ini akan mengkonsumsi banyak sumber daya bandwidth dan server.
Hal terbesar tentang API Websocket adalah bahwa server dan klien dapat mendorong informasi satu sama lain kapan saja dalam kisaran waktu tertentu. Setelah membuat koneksi, server dapat secara aktif mengirimkan data ke klien.
Selain itu, informasi header yang dipertukarkan antara server dan klien sangat kecil.
WebSocket tidak terbatas pada mode komunikasi dalam AJAX (atau XHR), karena teknologi AJAX mengharuskan klien untuk memulai permintaan, sementara server dan klien WebSocket dapat saling mendorong informasi;
Untuk pengantar terperinci untuk pesan AJAX, COMET, WebSocket dan Websocket, Anda dapat merujuk ke http://www.shaoqun.com/a/54588.aspx Web Design] Ajax, Comet, dan Websocket.
Jika saya punya waktu di masa depan, saya akan menuliskannya.
3. Cara menggunakan WebSocket
Klien
Di browser yang mendukung WebSocket, setelah membuat soket. Anda dapat menanggapi soket melalui empat acara: Onopen, OnMessage, dan Onclose, yaitu, Onerror.
Contoh sederhana
var ws = WebSocket baru (ws: // localhost: 8080); ws.onopen = function () {console.log (terbuka); C.Send (halo);}; ws.onmessage = function (evt) {console.log (evt.data)}; ws.onclose = function (evt) {console.log (WebSocketclosed!);}; ws.onError = function (evt) {console.log (WebSocketerrer;1.var ws = WebSocket baru (ws: // localhost: 8080);
Untuk mengajukan objek WebSocket, parameter adalah alamat server yang perlu dihubungkan. Sama seperti protokol HTTP, URL protokol Websocket dimulai dengan WS: //, dan protokol Websocket yang aman dimulai dengan WSS: //.
ws.send (halo);
Digunakan untuk mengirim pesan ke server
2.ws.onopen = function () {console.log (terbuka)};
Saat Websocket berhasil dibuat, acara OnOpen akan dipicu
3.ws.onMessage = function (evt) {console.log (evt.data)};
Ketika klien menerima pesan yang dikirim oleh server, acara OnMessage akan dipicu. Parameter EVT.Data berisi data yang dikirimkan oleh server.
4.ws.onclose = function (evt) {console.log (WebSocketClosed!); };
Ketika klien menerima permintaan untuk menutup koneksi yang dikirim oleh server, acara OnClose dipicu
5.ws.onError = function (evt) {console.log (WebSocketerror!); };
Jika koneksi, pemrosesan, menerima, dan mengirim data gagal, acara OnError akan dipicu
Kita dapat melihat bahwa semua operasi dipicu oleh peristiwa, sehingga UI tidak akan memblokir, memungkinkan UI memiliki waktu respons yang lebih cepat dan pengalaman pengguna yang lebih baik.
Sisi server
Saat ini, ada banyak perangkat lunak server yang mendukung WebSocket, seperti Node.js, Jetty, Tomcat, dll.
Di sini saya menggunakan Tomat 7.0 dan Eclipse4.2
Tomcat, gunakan Websocket terlebih dahulu untuk mengimpor toples yang relevan
Kelas -kelas yang terkait dengan WebSocket yang disediakan oleh TomCat7 semuanya terletak di paket org.apache.catalina.websocket (implementasi paket org.apache.catalina.websocket terkandung dalam file catalina.jar
Di sini kami hanya mengimpor semua tomcat
Di Build Path-> Configure Build Path-> Librarise-> Tambahkan Library-> Server Runtime-> Apache Tomcat V7.0
gambar
Juga, impor paket berikut
impor org.apache.catalina.websocket.messageInbound;
impor org.apache.catalina.websocket.streaminBound;
impor org.apache.catalina.websocket.wsoutbound;
impor org.apache.catalina.websocket.websocketservlet;
Kami membutuhkan dua kelas
Yang pertama digunakan untuk menangani permintaan WebSocket
Yang kedua digunakan untuk menangani setiap tugas websocket tertentu
Kategori pertama
SocketServer kelas publik memperluas WebSocketServlet {
private static final long serialversionuid = 1L;
//…
@Mengesampingkan
streaminbound createwebsocketinbound (string arg0,
Httpservletrequest arg1) {
// TODO Stub Metode yang dihasilkan otomatis
mengembalikan obrolan baru (pengguna);
}
}
Servlet ini mewarisi dari WebSocketServlet dan mengimplementasikan metode kreatewebsocketinbound. Metode ini mengembalikan instance dari kelas kedua.
Kategori kedua
CHAT CHATWEBSOCKET KELAS PUBLIK Extends MessageInbound {
@Mengesampingkan
Void OnTextMessage (pesan charbuffer) yang dilindungi {charbuffer {CharBuffer {CharBuffer {
}
@Mengesampingkan
void onopen yang dilindungi (wsoutbound outbound) {
}
@Mengesampingkan
void onclose yang dilindungi (status int) {
}
@Mengesampingkan
Void OnBinaryMessage (byteBuffer arg0) yang dilemparkan IOException {
}
// sisanya sedikit
}
Void OnTextMessage (Pesan CharBuffer) yang dilindungi IoException {}
Respons pesan teks
Void OnBinaryMessage (byteBuffer arg0) yang dilemparkan IOException {}
Respons pesan biner
void onopen yang dilindungi (outbound wsoutbound) {}
Peristiwa yang dipicu dengan membuat koneksi
void onclose yang dilindungi (status int) {}
Acara ditembakkan saat menutup koneksi
4. Kode program
bagian html
<! Doctype html>
<Html>
<head>
<Meta Charset = UTF-8>
<type skrip = teks/javascript src = js/jQuery.js> </script>
<type skrip = teks/javascript src = js/socket.js> </script>
<title> unt judul dokumen </iteme>
</head>
<bahasa skrip = javascript>
</script>
<body>
<able>
<tr>
<td> pesan </td>
<td> <input type = Text id = Message> </td>
</tr>
<tr>
<td> Nama </td>
<td> <input type = Text id = OtherName> </td>
</tr>
<tr>
<td> <input id = sendbutton type = value tombol = kirim ontClick = klik disabled = true>
</input> </td>
</tr>
</boable>
<script>
</script>
</body>
</html>
bagian JS (tidak ada penjelasan tentang bagian jQuery)
var username = window.prompt (masukkan nama Anda :);
Document.write (selamat datang <p id =/username/>+nama pengguna+</p>);
if (! window.websocket && window.mozwebsocket)
window.websocket = window.mozwebsocket;
if (! window.websocket)
waspada (tidak ada dukungan);
var ws;
$ (dokumen) .ready (function () {
$ (#sendbutton) .attr (dinonaktifkan, false);
$ (#sendbutton) .klick (sendmessage);
startwebsocket ();
})
fungsi sendmessage ()
{
var OtherName = $ (#OtherName) .val ();
var msg = msg/t+nama pengguna+_+nama lain+_+$ (#pesan) .val ();
kirim (msg);
}
Fungsi Kirim (Data)
{
console.log (kirim:+data);
ws.send (data);
}
fungsi startwebsocket ()
{
ws = WebSocket baru (ws: // + location.host +/websocket/socketserver);
ws.onopen = function () {
Console.log (Success Open);
$ (#sendbutton) .attr (dinonaktifkan, false);
};
ws.onmessage = fungsi (acara)
{
console.log (terima:+event.data);
handleData (event.data);
};
ws.onclose = function (event) {
Console.log (Socket yang diberitahukan klien telah ditutup, acara);
};
}
Fungsi HandleData (Data)
{
var vals = data.split (/t);
var msgtype = vals [0];
sakelar (msgtype)
{
Nama kasus:
var msg = vals [1];
var mes = name+/t+msg+_+nama pengguna;
kirim (mes);
merusak;
Case MSG:
var val2s = vals [1] .split (_);
var dari = val2s [0];
var pesan = val2s [2];
peringatan (dari+:+pesan);
merusak;
bawaan:
merusak;
}
}
Bagian java
impor java.io.ioException;
impor java.nio.bytebuffer;
impor java.nio.charbuffer;
impor javax.servlet.http.httpservletRequest;
impor java.util.set;
impor java.util.concurrent.copyonwriteArrayset;
impor org.apache.catalina.websocket.messageInbound;
impor org.apache.catalina.websocket.streaminBound;
impor org.apache.catalina.websocket.wsoutbound;
impor org.apache.catalina.websocket.websocketservlet;
SocketServer kelas publik memperluas WebSocketServlet {
private static final long serialversionuid = 1L;
set akhir publik <ChatWebSocket> Users = new copyonWriteArrayset <ChatWebsocket> ();
Public Static Int UserNBURE = 1;
@Mengesampingkan
streaminbound createwebsocketinbound (string arg0,
Httpservletrequest arg1) {
// TODO Stub Metode yang dihasilkan otomatis
mengembalikan obrolan baru (pengguna);
}
CHAT CHATWEBSOCKET KELAS PUBLIK Extends MessageInbound {
nama pengguna string pribadi;
Set Private <ChatWebsocket> Users = new copyonWriteArrayset <ChatWebsocket> () ;;
obrolan publik () {
}
Public Chatwebsocket (set <obatwebsocket> pengguna) {
this.users = pengguna;
}
@Mengesampingkan
Void OnTextMessage (pesan charbuffer) yang dilindungi {charbuffer {CharBuffer {CharBuffer {
// yang diproses di sini adalah data teks
}
public void onMessage (string data) {
String [] val1 = data.split (// t);
if (val1 [0] .Equals (name))
{
String [] val2 = val1 [1] .split (_);
untuk (chatwebsocket pengguna: pengguna) {
if (user.username.equals (val2 [0])) {
user.username = val2 [1];
}
}
}
lain jika (val1 [0] .Equals (msg))
{
String [] val2 = val1 [1] .split (_);
untuk (chatwebsocket pengguna: pengguna) {
if (user.username.equals (val2 [1])) {
mencoba {
Charbuffer temp = charbuffer.wrap (data);
user.getWsoutbound (). writeTextMessage (temp);
} catch (ioException e) {
// TODO Blok tangkapan yang dihasilkan otomatis
e.printstacktrace ();
}
}
}
}
kalau tidak
{
System.out.println (kesalahan);
}
}
@Mengesampingkan
void onopen yang dilindungi (wsoutbound outbound) {
// this.connection = koneksi;
this.username = # + string.ValueOf (angka pengguna);
Bilangan pengguna ++;
mencoba {
String message = name + /t + this.username;
Charbuffer buffer = charbuffer.wrap (pesan);
this.getWsoutbound (). writeTextMessage (buffer);
} catch (ioException e) {
// TODO Blok tangkapan yang dihasilkan otomatis
e.printstacktrace ();
}
Users.add (ini);
}
@Mengesampingkan
void onclose yang dilindungi (status int) {
Users.remove (ini);
}
@Mengesampingkan
Void OnBinaryMessage (byteBuffer arg0) yang dilemparkan IOException {
}
}
}
menjelaskan
Ide saya di sini adalah
1 Saat mengakses, setiap pengguna pertama -tama harus memasukkan namanya, dan kemudian mengirim permintaan koneksi ke server.
2 Setelah server menerima permintaan koneksi klien, itu akan chatwebsocket baru (pengguna); Untuk memproses permintaan ini dan menambahkannya ke daftar pengguna online. Pada saat ini, server belum tahu nama pelanggan. Ini akan mengasumsikan nama untuk pengguna ini, #1, dan server akan mengirim nama + /t + #1 ke klien, siapa nama Anda?
3 Ketika klien menerima pesan ini, ia akan tahu bahwa server bertanya pada dirinya sendiri apa namanya, jadi klien akan mengirim nama+/t+#1+_+namanya sendiri ke server (nama saya xxx)
4 Setelah menerima pesan ini, server mencari di daftar pengguna online saat ini berdasarkan #1, dan menggantikan #1 dengan nama pelanggan, sehingga server akan mengetahui nama pelanggan.
5 Ketika pelanggan pergi, server akan memicu acara OnClose, dan server akan menghapus pengguna saat ini dari daftar online.
Gunakan gambar untuk menggambar sesuatu seperti ini (digambar dengan buruk, -_- !!)
Kode
JS
ws = WebSocket baru (ws: // + location.host +/websocket/socketserver);
Terhubung ke server
Jawa
streaminbound createwebsocketinbound (string arg0,
Httpservletrequest arg1) {
// TODO Stub Metode yang dihasilkan otomatis
mengembalikan obrolan baru (pengguna);
}
Buat chatwebsocket untuk menangani permintaan ini dan memicu acara OnOpen dari objek chatwebsocket
@Mengesampingkan
void onopen yang dilindungi (wsoutbound outbound) {
// this.connection = koneksi;
this.username = # + string.ValueOf (angka pengguna);
Bilangan pengguna ++;
mencoba {
String message = name + /t + this.username;
Charbuffer buffer = charbuffer.wrap (pesan);
this.getWsoutbound (). writeTextMessage (buffer);
} catch (ioException e) {
// TODO Blok tangkapan yang dihasilkan otomatis
e.printstacktrace ();
}
Users.add (ini);
}
Dengan asumsi nama untuk klien ini, mengirimkan nama yang diasumsikan nama+/t+ ke klien, dan menambahkan klien ke daftar klien yang saat ini terhubung
JS
Fungsi HandleData (Data)
{
var vals = data.split (/t);
var msgtype = vals [0];
sakelar (msgtype)
{
Nama kasus:
var msg = vals [1];
var mes = name+/t+msg+_+nama pengguna;
kirim (mes);
merusak;
// ………
}
}
Terima dan proses pesan yang dikirim oleh server, dan temukan bahwa server bertanya siapa namanya, jadi itu mengirim nama+/t+nama yang diasumsikan+_+ke server.
Jawa
public void onMessage (string data) {
String [] val1 = data.split (// t);
if (val1 [0] .Equals (name))
{
String [] val2 = val1 [1] .split (_);
untuk (chatwebsocket pengguna: pengguna) {
if (user.username.equals (val2 [0])) {
user.username = val2 [1];
}
}
}
// ………
}
Memproses dan menerima pesan yang dikirim oleh klien, dan temukan bahwa klien membalas namanya, jadi cari dalam daftar klien yang saat ini terhubung berdasarkan nama yang sebelumnya diasumsikan, dan ubah nama samaran menjadi nama asli
JS
fungsi sendmessage ()
{
var OtherName = $ (#OtherName) .val ();
var msg = msg/t+nama pengguna+_+nama lain+_+$ (#pesan) .val ();
kirim (msg);
}
Klien memulai percakapan dengan orang lain, dan format pesan adalah: msg+namanya sendiri+_+nama berlawanan+_+pesan
Jawa
public void onMessage (string data) {
/// …………
lain jika (val1 [0] .Equals (msg))
{
String [] val2 = val1 [1] .split (_);
untuk (chatwebsocket pengguna: pengguna) {
if (user.username.equals (val2 [1])) {
mencoba {
Charbuffer temp = charbuffer.wrap (data);
user.getWsoutbound (). writeTextMessage (temp);
} catch (ioException e) {
// TODO Blok tangkapan yang dihasilkan otomatis
e.printstacktrace ();
}
}
}
}
/// …………
}
Ditemukan bahwa pesan tersebut dikirim oleh pelanggan. Menurut nama pihak lain, cari dalam daftar pelanggan yang saat ini terhubung dan kirim pesan kepadanya.
JS
Fungsi HandleData (Data)
{
var vals = data.split (/t);
var msgtype = vals [0];
sakelar (msgtype)
{
///…
Case MSG:
var val2s = vals [1] .split (_);
var dari = val2s [0];
var pesan = val2s [2];
peringatan (dari+:+pesan);
merusak;
bawaan:
merusak;
}
}
Ditemukan bahwa itu adalah pesan yang dikirim oleh pelanggan lain, dan itu ditampilkan melalui peringatan
Jawa
@Mengesampingkan
void onclose yang dilindungi (status int) {
Users.remove (ini);
}
Menemukan pelanggan telah pergi, hapus pelanggan dari daftar pelanggan yang terhubung
Di mana harus meningkatkan
1. Jika klien A mengirimkan pesan ke B dan B tidak online, pesan tersebut dapat disimpan dalam database. Ketika B ditemukan online, itu akan diambil dari database dan dikirim ke B.
2 Ketika server mengirimkan nama Anda, itu dapat menambah mekanisme batas waktu. Jika klien tidak membalas apa yang disebut dalam periode waktu tertentu, klien dapat menghapus klien dari daftar online.