Функция Push Push, завершенная WebSocket и Java, используется сервером Tomcat7.0. Некоторые вещи рассматриваются самостоятельно, и я не знаю, являются ли они уместными или неуместными. Пожалуйста, прости меня и укажите на них.
Проще говоря, клиент A может отправлять сообщения клиенту B, но есть много мест, которые можно расширить.
например
1. Если после присоединения к базе данных, когда отправляет сообщение, клиент B не находится в Интернете, сервер будет хранить сообщение в базе данных. После того, как клиент B будет в сети, сообщение будет получено и отправлено клиенту B.
2. Сервер также может отправлять сообщения любому клиенту.
Скриншот действующего эффекта программы выглядит следующим образом (проверено под Chrome, Sogou и Firefox): код будет дан в конце
Во -первых, мы открываем браузер и отображаются, чтобы ввести ваше имя. Здесь я вхожу в SOAR
При открытии второго браузера здесь я ввожу счет
Это если я отправлю привет, Билл, я буду на счет, нажмите «Отправить
Вы можете увидеть это в другом браузере
WebSocket
1. Что такое WebSocket?
WebSocket-это технология, которая генерируется для решения связи в реальном времени между клиентами и серверами. Суть состоит в том, чтобы создать соединение TCP для обмена данными после протокола HTTP/HTTPS.
После этого сервер и клиент общаются в режиме реального времени через это соединение TCP.
2. Преимущества WebSocket
В прошлом мы внедрили технологию Push, используя опросы. При характерном интервале времени браузер автоматически выпускает запрос и активно оттягивает сообщения сервера. В этом случае нам нужно постоянно отправлять запросы на сервер. Тем не менее, заголовок HTTP -запроса очень длинный, и данные, содержащиеся в нем Он будет потреблять много пропускной способности и ресурсов сервера.
Самая большая вещь в API WebSocket состоит в том, что сервер и клиент могут в любое время в течение определенного диапазона времени в течение определенного диапазона времени. После установления соединения сервер может активно передавать данные клиенту.
Кроме того, информация заголовка, обмениваемая между сервером и клиентом, очень мала.
WebSocket не ограничивается коммуникацией в режиме AJAX (или XHR), потому что технология AJAX требует, чтобы клиенты инициировали запросы, в то время как серверы WebSocket Servers и клиенты могут выдвигать информацию друг к другу;
Для получения подробного введения в сообщения AJAX, Comet, WebSocket и WebSocket, вы можете обратиться к http://www.shaoqun.com/a/54588.aspx веб -дизайн] Ajax, Comet и Websocket.
Если у меня будет время в будущем, я напишу это.
3. Как использовать WebSocket
Клиент
В браузере, который поддерживает WebSocket, после создания сокета. Вы можете реагировать на розетки через четыре события: OnoPen, OnMessage и Onclose, то есть Onerror.
Простой пример
var ws = new WebSocket (ws: // localhost: 8080); ws.onopen = function () {console.log (open); ws.send (hello);}; ws.onmessage = function (evt) {console.log (evt.data)}; ws.onclose = function (evt) {console.log (websocketcocked!);}; ws.onerror = function (evt) {console.log (websocketocketerror!);1.var ws = new WebSocket (WS: // localhost: 8080);
Чтобы подать заявку на объект WebSocket, параметры являются адресом сервера, который необходимо подключить. Так же, как протокол HTTP, URL -адрес протокола WebSocket начинается с WS: //, а протокол Secure WebSocket начинается с WSS: //.
Ws.send (Привет);
Используется для отправки сообщений на сервер
2.ws.onopen = function () {console.log (open)};
Когда WebSocket будет успешно создан, событие OnoPen будет вызвано
3.ws.onmessage = function (evt) {console.log (evt.data)};
Когда клиент получает сообщение, отправленное сервером, событие OnMessage будет запускается. Параметр evt.data содержит данные, передаваемые сервером.
4.ws.onclose = function (evt) {console.log (websocketclosed!); };
Когда клиент получает запрос на закрытие подключения, отправленного сервером, событие Onclose запускается
5.ws.onerror = function (evt) {console.log (websocketerror!); };
Если подключение, обработка, получение и отправка данных не выполняется, событие Onerror будет вызвано
Мы видим, что все операции запускаются событиями, так что пользовательский интерфейс не будет блокировать, что позволяет пользовательскому интерфейсу более быстрое время отклика и улучшение пользовательского опыта.
Серверная сторона
В настоящее время существует много серверного программного обеспечения, которое поддерживает WebSocket, такие как Node.js, Jetty, Tomcat и т. Д.
Здесь я использую Tomat 7.0 и Eclipse4.2
Tomcat, сначала используйте WebSocket, чтобы импортировать соответствующую банку
Классы, связанные с WebSocket, предоставленным Tomcat7, расположены в пакете org.apache.catalina.websocket (реализация пакета org.apache.catalina.websocket содержится в файле Catalina.jar
Здесь мы просто импортируем все Tomcat
В Path-Path-> Configure Pult Path-> Librarise-> Добавить Library-> Server Runtime-> Apache Tomcat v7.0
изображение
Кроме того, импортируйте следующие пакеты
Импорт org.apache.catalina.websocket.messageinbound;
Импорт org.apache.catalina.websocket.streaminbound;
Импорт org.apache.catalina.websocket.wsoutbound;
Импорт org.apache.catalina.websocket.websocketservlet;
Нам нужно два класса
Первый используется для обработки запросов WebSocket
Второй используется для выполнения каждой конкретной задачи WebSocket
Первая категория
открытый класс SocketServer Extens WebSocketServlet {
Частный статический конечный длинный SerialVersionuid = 1L;
//…
@Override
Защищенный потокотисый
Httpservletrequest arg1) {
// TODO Автогенерированный метод заглушка
вернуть новый ChatWebSocket (пользователи);
}
}
Этот сервлет наследует от WebSocketServlet и реализует метод CreateWebSockeCocketInbound. Этот метод возвращает экземпляр второго класса.
Вторая категория
открытый класс CatWebSocket Extends MessageInbound {
@Override
Защищенный void OntextMessage (сообщение Charbuffer) бросает ioException {
}
@Override
защищенная void onopen (wsoutbound outbound) {
}
@Override
Защищенный void onclose (int status) {
}
@Override
Защищенная void OnBinaryMessage (bytebuffer arg0) бросает ioException {
}
// остальное просто немного
}
Protected void OntextMessage (сообщение Charbuffer) бросает ioException {}
Ответ текстового сообщения
Защищенный void OnBinaryMessage (bytebuffer arg0) бросает ioException {}
Бинарный ответ сообщения
Защищенная void onoPen (wsoutbound outbound) {}
События, вызванные установлением соединения
Защищенный void onclose (int status) {}
События, выпущенные при закрытии соединения
4. Программный код
HTML Part
<! Doctype html>
<html>
<голова>
<meta charset = utf-8>
<script type = text/javascript src = js/jquery.js> </script>
<script type = text/javascript src = js/socket.js> </script>
<title> unt назвал документ </title>
</head>
<сценарий языка = javascript>
</script>
<тело>
<Таблица>
<tr>
<Td> Сообщение </td>
<Td> <input type = text id = сообщение> </td>
</tr>
<tr>
<TD> Имя </TD>
<Td> <input type = text id = sothername> </td>
</tr>
<tr>
<TD> <INPUT ID = SendButton Type = кнопка value = send onClick = click disabled = true>
</input> </td>
</tr>
</table>
<Скрипт>
</script>
</body>
</html>
JS часть (нет объяснения о части JQUERY)
var username = window.prompt (введите свое имя :);
document.write (добро пожаловать <p id =/username/>+username+</p>);
if (! window.websocket && window.mozwebsocket)
window.websocket = window.mozwebsocket;
if (! window.websocket)
оповещение (без поддержки);
var ws;
$ (document) .ready (function () {
$ (#sendbutton) .attr (отключен, false);
$ (#sendbutton) .click (sendmessage);
startWebSocket ();
})
функция sendmessage ()
{
var sothername = $ (#othername) .val ();
var msg = msg/t+username+_+othername+_+$ (#message) .val ();
отправить (msg);
}
Функция отправить (данные)
{
console.log (send:+data);
Ws.send (данные);
}
function startWebSocket ()
{
ws = new WebSocket (ws: // + location.host +/websocket/socketserver);
ws.onopen = function () {
console.log (успех открыт);
$ (#sendbutton) .attr (отключен, false);
};
ws.onmessage = function (событие)
{
console.log (ate:+event.data);
handleledata (event.data);
};
ws.onclose = function (event) {
console.log (клиент уведомленная сокет закрылся, событие);
};
}
функция обработки (данные)
{
var als = data.split (/t);
var msgtype = vals [0];
Переключатель (MSGTYPE)
{
Название корпуса:
var msg = vals [1];
var mes = name+/t+msg+_+имя пользователя;
отправить (mes);
перерыв;
Case MSG:
var val2s = vals [1] .split (_);
var from = val2s [0];
var message = val2s [2];
оповещение (от+:+сообщение);
перерыв;
по умолчанию:
перерыв;
}
}
Java Part
импортировать java.io.ioexception;
Импорт java.nio.bytebuffer;
Импорт java.nio.charbuffer;
Импорт javax.servlet.http.httpservletrequest;
импортировать java.util.set;
import java.util.concurrent.copyonwritearrayset;
Импорт org.apache.catalina.websocket.messageinbound;
Импорт org.apache.catalina.websocket.streaminbound;
Импорт org.apache.catalina.websocket.wsoutbound;
Импорт org.apache.catalina.websocket.websocketservlet;
открытый класс SocketServer Extens WebSocketServlet {
Частный статический конечный длинный SerialVersionuid = 1L;
public final Set <chatwebsocket> users = new CopeonWritearRaySet <TatWebSocket> ();
Public Static int usermumber = 1;
@Override
Защищенный потокотисый
Httpservletrequest arg1) {
// TODO Автогенерированный метод заглушка
вернуть новый ChatWebSocket (пользователи);
}
открытый класс CatWebSocket Extends MessageInbound {
частное имя пользователя;
Private Set <chatwebsocket> users = new CopeonWritearRaySet <TatWebSocket> () ;;
public CatWebSocket () {
}
public ChatWebSocket (SET <TatWebSocket> пользователи) {
this.users = пользователи;
}
@Override
Защищенный void OntextMessage (сообщение Charbuffer) бросает ioException {
// то, что обрабатывается здесь, это текстовые данные
}
public void onMessage (String Data) {
String [] val1 = data.split (// t);
if (val1 [0] .equals (имя))
{
String [] val2 = val1 [1] .split (_);
для (chatwebsocket user: users) {
if (user.username.equals (val2 [0])) {
user.username = val2 [1];
}
}
}
иначе if (val1 [0] .equals (msg)))
{
String [] val2 = val1 [1] .split (_);
для (chatwebsocket user: users) {
if (user.username.equals (val2 [1])) {
пытаться {
Charbuffer temp = charbuffer.wrap (data);
user.getWsoutBound (). wriseTexTmessage (temp);
} catch (ioException e) {
// Todo Auto Generated Catch Blach
e.printstacktrace ();
}
}
}
}
еще
{
System.out.println (ошибка);
}
}
@Override
защищенная void onopen (wsoutbound outbound) {
// this.connection = connection;
this.username = # + string.valueof (пользователь);
Пользователь ++;
пытаться {
String message = name + /t + this.username;
Charbuffer buffer = charbuffer.wrap (сообщение);
this.getwsoutbound (). writeTexTmessage (буфер);
} catch (ioException e) {
// Todo Auto Generated Catch Blach
e.printstacktrace ();
}
users.add (это);
}
@Override
Защищенный void onclose (int status) {
users.remove (это);
}
@Override
Защищенная void OnBinaryMessage (bytebuffer arg0) бросает ioException {
}
}
}
объяснять
Моя идея здесь
1 При доступе каждый пользователь сначала должен ввести свое или ее имя, а затем отправлять запрос на соединение на сервер.
2 После того, как сервер принимает запрос на подключение клиента, он будет новым Chatwebsocket (пользователи); Чтобы обработать этот запрос и добавить его в онлайн -список пользователей. В настоящее время сервер еще не знает имя клиента. Он предполагает имя для этого пользователя, #1, и сервер отправит имя + /t + #1, как ваше имя?
3 Когда клиент получает это сообщение, он будет знать, что сервер спрашивает себя, как его имя, поэтому клиент отправит имя+/t+#1+_+его собственное имя на сервер (мое имя XXX)
4 После получения этого сообщения сервер ищет поиск в списке онлайн -пользователей в настоящее время на основе #1 и заменяет № 1 на имя клиента, чтобы сервер узнал имя клиента.
5 Когда клиент уйдет, сервер запустит событие Onclose, а сервер удалит текущего пользователя из онлайн -списка.
Используйте картинки, чтобы нарисовать что -то вроде этого (плохо, -_- !!)
Код
младший
ws = new WebSocket (ws: // + location.host +/websocket/socketserver);
Подключиться к серверу
Ява
Защищенный потокотисый
Httpservletrequest arg1) {
// TODO Автогенерированный метод заглушка
вернуть новый ChatWebSocket (пользователи);
}
Создайте чат -weebsocket для обработки этого запроса и запустить событие OnoPen объекта ChatWebSocket
@Override
защищенная void onopen (wsoutbound outbound) {
// this.connection = connection;
this.username = # + string.valueof (пользователь);
Пользователь ++;
пытаться {
String message = name + /t + this.username;
Charbuffer buffer = charbuffer.wrap (сообщение);
this.getwsoutbound (). writeTexTmessage (буфер);
} catch (ioException e) {
// Todo Auto Generated Catch Blach
e.printstacktrace ();
}
users.add (это);
}
Предполагая имя для этого клиента, отправляя предполагаемое имя имени+/t+ клиенту и добавление клиента в список подключенных клиентов в настоящее время
младший
функция обработки (данные)
{
var als = data.split (/t);
var msgtype = vals [0];
Переключатель (MSGTYPE)
{
Название корпуса:
var msg = vals [1];
var mes = name+/t+msg+_+имя пользователя;
отправить (mes);
перерыв;
// ………
}
}
Примите и обработайте сообщение, отправленное сервером, и обнаружите, что сервер спросил его, как его имя, поэтому он отправил имя+/t+предполагаемое имя+_+на сервер.
Ява
public void onMessage (String Data) {
String [] val1 = data.split (// t);
if (val1 [0] .equals (имя))
{
String [] val2 = val1 [1] .split (_);
для (chatwebsocket user: users) {
if (user.username.equals (val2 [0])) {
user.username = val2 [1];
}
}
}
// ………
}
Обработайте и примите сообщение, отправленное клиентом, и обнаружите, что клиент ответил на свое имя, поэтому поиск в подключенном к ныне списке клиентов на основе ранее предполагаемого имени и превратите псевдоним в настоящее имя
младший
функция sendmessage ()
{
var sothername = $ (#othername) .val ();
var msg = msg/t+username+_+othername+_+$ (#message) .val ();
отправить (msg);
}
Клиент инициирует разговор с другим человеком, а формат сообщения: msg+его собственное имя+_+противоположное имя+_+Сообщение
Ява
public void onMessage (String Data) {
/// …………
иначе if (val1 [0] .equals (msg)))
{
String [] val2 = val1 [1] .split (_);
для (chatwebsocket user: users) {
if (user.username.equals (val2 [1])) {
пытаться {
Charbuffer temp = charbuffer.wrap (data);
user.getWsoutBound (). wriseTexTmessage (temp);
} catch (ioException e) {
// Todo Auto Generated Catch Blach
e.printstacktrace ();
}
}
}
}
/// …………
}
Установлено, что сообщение отправляется клиентом. Согласно имени другой стороны, поиск в в настоящее время подключенном списке клиентов и отправьте ему сообщение.
младший
функция обработки (данные)
{
var als = data.split (/t);
var msgtype = vals [0];
Переключатель (MSGTYPE)
{
/// ...
Case MSG:
var val2s = vals [1] .split (_);
var from = val2s [0];
var message = val2s [2];
оповещение (от+:+сообщение);
перерыв;
по умолчанию:
перерыв;
}
}
Было обнаружено, что это было сообщение, отправленное другим клиентом, и оно было отображено через предупреждение
Ява
@Override
Защищенный void onclose (int status) {
users.remove (это);
}
Обнаружение клиента ушло, удалите клиента из списка подключенных клиентов
Где улучшить
1. Если клиент A отправляет сообщение B, а B не является онлайн, сообщение можно хранить в базе данных. Когда B будет найден в сети, он будет извлечен из базы данных и отправлена B.
2 Когда сервер отправляет ваше имя, он может добавить механизм тайм -аута. Если клиент не отвечает на то, что его называют в течение определенного периода времени, клиент может удалить клиента из онлайн -списка.