Предисловие
HTML5 WebSocket реализует двустороннюю связь между сервером и браузером. Двухсторонняя связь делает разработку сообщения сервера проще. Наиболее распространенными являются мгновенное общение и приложения, которые требуют высококачественной информации в режиме реального времени. Большая часть предыдущего сообщения сервера нажимает используемые технологии «опроса» и «длинного подключения», оба из которых могут понести значительные накладные расходы на сервере, а производительность в реальном времени не была особенно высокой. Технология WebSocket будет нести лишь небольшие накладные расходы и особенно высока в режиме реального времени. Давайте начнем с объяснения того, как использовать технологию WebSocket для разработки чатов. В этом примере используется сервер Tomcat7. Каждый сервер имеет разные реализации WebSocket, поэтому этот экземпляр может быть запущен только на сервере Tomcat. Тем не менее, Spring запустила API WebSocket, который совместим с реализацией каждого сервера. Вы можете проконсультироваться с соответствующей информацией, чтобы понять. Я не буду представлять его здесь. Следующая картина - это рендеринг чата:
В этом примере реализуется толчок сообщений в режиме реального времени, а также онлайн и автономные уведомления пользователей чата также реализованы. Давайте начнем подробно объяснить, как его реализовать.
Обработка бэкэнд
Tomcat в основном реализует WebSocket, полагаясь на класс org.apache.catalina.websocket.messageinbound. Этот класс находится в {Tomcat_home} /lib/catalina.jar, поэтому, когда вы развиваете, вам нужно представить Catalina.jar и Tomcat-coyote.jar. Следующий код подвергается воздействию адреса сервлета клиента:
пакет com.ibcio; Импорт javax.servlet.annotation.webservlet; Импорт javax.servlet.http.httpservletrequest; Импорт org.apache.catalina.websocket.streaminbound; @Webservlet (urlpatterns = {"/message"}) // Если вы хотите получить запросы от протокола браузера WS: //, вы должны реализовать открытый класс WebSocketServlet. public static int online_user_count = 1; public String getUser (httpservlectrequest) {return (string) request.getSession (). getattribute ("user"); } // В отличие от обычных сервлетов, необходимо реализовать CreateWebSocketInbound, и пользовательский объект подключения WebSocket инициализируется здесь @Override Protected Streambound CreateBeSocketInbound (строковый субпротокол, httpservlectrequest) {return new WebSocketMessAgeinBound (this.getUser (запрос)); }} Этот сервлет несколько отличается от обычных сервлетов. Он унаследовал класс веб -билетов и необходимо переопределить метод CreateWebSocketInbound. Атрибут пользователя в сеансе в этом классе устанавливается, когда пользователь вводит index.jsp, и записывает псевдоним текущего пользователя. Ниже приведен код класса WebSocketCocketMessAgeInbound, реализованный самим собой:
пакет com.ibcio; импортировать java.io.ioexception; Импорт java.nio.bytebuffer; Импорт java.nio.charbuffer; Импорт net.sf.json.jsonobject; Импорт org.apache.catalina.websocket.messageinbound; Импорт org.apache.catalina.websocket.wsoutbound; public class websocketmessageinbound extends messageInbound {// Имя пользователя текущего подключения является частным пользователем строки; public websocketmessageinbound (String user) {this.user = user; } public String getUser () {return this.user; } // Событие, запускаемое путем установления соединения @Override, защищенного void onoPen (wsoutBound outbound) {// запустить событие соединения и добавить соединение в пул соединений jsonObject result = new jsonObject (); result.element ("type", "user_join"); result.element («пользователь», this.user); // Нажмите сообщение о том, что текущий пользователь онлайн для всех пользователей онлайн -пользователей WebSocketCeceSgeInboundpool.sendmessage (result.tostring ()); result = new jsonObject (); result.element ("type", "get_online_user"); result.element ("list", websockecocketmessageinboundpool.getonlineuser ()); // Добавить текущий объект подключения в пул соединений webSocketCeceSgeInboundpool.addmessageinbound (this); // Отправить текущий онлайн -список пользователей в текущий подключение webSocketCocketInboundpool.sendmessagetouser (this.user, result.tostring ()); } @Override Protected void onclose (int status) {// запускает событие закрытия и удалите соединение из пула соединений WebSocketCeceSgeInboundpool.RemoVemessageInbound (this); JsonObject result = new jsonObject (); result.element ("type", "user_leave"); result.element («пользователь», this.user); // Отправить сообщение онлайн -пользователю, что текущий пользователь выходит из WebSocketCocketInboundpool.sendmessage (result.tostring ()); } @Override Protected void OnBinaryMessage (ByteBuffer Message) бросает ioException {бросить новое UnsupportedOperationException («двоичное сообщение не поддерживается.»); } // Событие запускается, когда клиент отправляет сообщение на сервер @Override Protected void OntextMessage (charbuffer message), выдвигает ioException {// Отправить сообщение всем онлайн -пользователям webSocketCeceInboundpool.sendmessage (message.toString ()); }} Код в основном реализует методы OnoPen, Onclose и OnTextMessage, которые обрабатывают пользователи онлайн, оффлайн и отправляют сообщения соответственно. В этом классе есть класс пула соединений WebsocketMessageInboundpool. Этот класс используется для управления соединениями в настоящее время онлайн -пользователей. Ниже приведен код этого класса:
пакет com.ibcio; импортировать java.io.ioexception; Импорт java.nio.charbuffer; импортировать java.util.hashmap; импортировать java.util.map; импортировать java.util.set; открытый класс webSocketMessageInboundpool {// Сохранить контейнер карты для подключения частной статической конечной карты <строка, websocketmessageinbound> connections = new Hashmap <String, websocketMessageInbound> (); // Добавить соединение в пул соединений Public Static void AddMessAgeInbound (webSocketMessAgeInbound inbound) {// Добавить System.out.println ("user:" + inbound.getUser () + "join .."); connections.put (inbound.getuser (), вход); } // Получить все онлайн -пользователи общедоступного статического набора <string> getOnlineUser () {return connections.keyset (); } public static void eMerlecteMessAgeInbound (webSocketMessAgeInbound inbound) {// Удалить систему соединения.out.println ("user:" + inbound.getUser () + "exit .."); Connections.remove (inbound.getUser ()); } public static void sendmessageToureser (String user, String Message) {try {// Отправить данные в конкретные пользователи System.out.println ("Отправить сообщение пользователю:" + user + ", content:" + message); Websocketmessageinbound inbound = connections.get (user); if (inbound! = null) {inbound.getwsoutbound (). writeTexTmessage (charbuffer.wrap (message)); }} catch (ioException e) {e.printstacktrace (); }} // Отправить сообщение всем пользователям public static void sendmessage (string message) {try {set <string> keyset = connections.keyset (); for (String Key: Keyset) {webSocketMessAgeInbound inbound = connections.get (key); if (inbound! = null) {System.out.println ("Отправить сообщение пользователю:" + key + ", содержимое сообщения:" + message); inbound.getwsoutbound (). writeTextMessage (charbuffer.wrap (сообщение)); }}} catch (ioException e) {e.printstacktrace (); }}} Столь на стойке регистрации
Приведенный выше код является кодом бэкэнда чата, который в основном состоит из 3 объектов, сервлета, объекта соединения и пула соединений. Ниже приведен код стойки регистрации. Код на стойке регистрации в основном реализует соединение с сервером и отображает список пользователей и список информации. Дисплей стойки регистрации использует структуру EXT. Студенты, которые не знакомы с EXT, могут иметь предварительное понимание Ext. Ниже приведен код index.jsp:
<%@ page language = "java" pageencoding = "utf-8" import = "com.ibcio.websocketmessageservlet"%> <%string user = (string) session.getattribute ("user"); if (user == null) {// генерировать прозвище для пользователя user = "uege" + webSocketMesseServlet.online_user_count; Websocketmessageservlet.online_user_count ++; session.setattribute («Пользователь», пользователь); } pagecontext.setattribute ("user", user); %> <html> <head> <tite> websocket Chat Room </title> <!-ввести файлы css-> <link rel = "styleSheet" type = "text/css" href = "ext4/resources/css/ext-all.css"> <link rel = "stylesheet" type = "css/css" href = "ext4/relse-lecthelet"/css "href =" ext4/rel = " rel = "styleSheet" type = "text/css" href = "css/websocket.css"/> <!- Package Development's input Ext JS и свой собственный реализованный WebScoket. -> <script type = "text/javascript" src = "ext4/ext-all-debug.js"> </script> <script type = "text/javascript" src = "websocket.js"> </script> <script type = "text/javascript"> var user = "$ {user}"; </script> </head> <body> <h1> websocket Chat Room </h1> <p> API, предоставленный стандартом HTML5, объединяется с богатой Ext Client Framework для реализации комнаты чата, которая имеет следующие характеристики: </p> <ul style = "Padding-left: 10px;"> <li> Полные данные. Коммуникация, которая отличается от таких технологий, как опрос и длинное соединение, и сохраняет ресурсы сервера </li> <li> в сочетании с ext for Page Display </li> <li> Пользователь онлайн и автономный уведомление </li> </ul> <div ID = "WebSocketocket_button"> </div> </body> </html> Отображение страницы в основном управляется в websocket.js. Ниже приведен код websocket.jsd:
// используется для отображения информации о чате пользователя ext.define ('messageContainer', {extend: 'ext.view.view', trackover: true, multielect: false, itemcls: 'l-im-message', itemselector: 'div.l-message', upitemcls: 'l-message-message-selectemcremesse-message:' l-message-message-message-message-message. {Overflow: «Auto», FounalColor: '#fff'}, TPL: ['<div> Не доверяйте денежным переводам, выигрышной информации или незнакомым телефонным призывам во время разговора. '<div> {content} </div>', '</div>', '</tpl>'], сообщения: [], initcomponent: function () {var me = this; 'Source']}); Сообщение ['' TimeStamp '] = ext.date.format (новая дата (сообщение [' 'timemplam]),' h: i: s '); if (message.from == user) {message.source = 'self'; } else {message.source = 'remote'; } me.store.add (сообщение); if (me.el.dom) {me.el.dom.scrolltop = me.el.dom.scrollheight; }}}); Этот код в основном реализует контейнер, который отображает сообщение. Ниже приведен код, который начинает выполнять после загрузки страницы:
Ext.onready (function () {// Создать поле ввода пользователя var input = ext.create ('ext.form.field.htmleditor', {region: 'south', высота: 120, enablefont: false, ensubleceedite: false, eNableAlignments: false, слушатели: {function () eventmanger.on (me.input {if (e.ctrlke === true && e.keycode == 13) {e.preventdefault (); Ext.create ('ext.panel.panel', {Region: 'Center', Mayout: 'Border', элементы: [Вход, вывод], кнопки: [{Text: 'Send', Handler: Send}]}); WebSocket (Encodeuri ('ws: // localhost: 8080/websocket/message')); } websocket.onclose = function () {// Соединение отключение win.setTitle (title + '(densuncted)'); } // Прием сообщения websocket.onmessage = function (сообщение) {var message = json.parse (message.data); // получение сообщений, отправленных пользователем if (message.type == 'message') {output.receive (message); } else if (message.type == 'get_online_user') {// Получить онлайн -список пользователей root root = OnternalUser.getRootNode (); Ext.each (message.list, function (user) {var node = root.createNode ({id: user, text: user, iconcls: 'user', leaf: true}); root.appendchild (node);}); } else if (message.type == 'user_join') {// Пользователь выходит в Интернет var root = OnlineUser.getRootNode (); var user = message.user; var node = root.createnode ({id: пользователь, текст: пользователь, iconcls: 'user', leaf: true}); root.appendchild (узел); } else if (message.type == 'user_leave') {// Пользователь выходит из строя var root = OnlineUser.getRootNode (); var user = message.user; var node = root.findchild ('id', user); root.RemoveChild (узел); }}}}}; // онлайн-дерево пользователя var oNLAYUSER = ext.create ('ext.tree.panel', {title: 'online', rootvisible: false, region: 'ast', ширина: 150, строки: false, usearrows: true, Autoscroll: true, split: true, iconcls: 'user-online', store: ext.create ('ext.data. Пользователь ', расширен: true, дети: []}})}); var title = 'добро пожаловать:' + user; // Отображение окна var win = ext.create ('ext.window.window', {название: название + '(не подключено)', макет: «граница», Iconcls: «Пользователь-выигрыш», Minwidth: 650, Minheight: 460, ширина: 650, amimatetarget: 'websocket_button', height: 460, элементы: dialog, intileterget: 'websocket_button', height: 460, элементы: dialog: intilet {render: function () {initWebSocket ();}}}); win.show (); // Отправить функцию сообщения send () {var message = {}; if (websocket! = null) {if (input.getValue ()) {ext.Apply (message, {from: user, content: input.getValue (), timeStamp: new Date (). getTime (), type: 'message'}); websocket.send (json.stringify (сообщение)); //output.receive(message); input.setValue (''); }} else {ext.msg.alert ('tip', 'Вы были отключены и не можете отправлять сообщения!'); }}}});Приведенный выше код - это код, который автоматически подключается к серверу после загрузки страницы, и создает интерфейс дисплея.
Уведомление
Два момента, чтобы отметить: после завершения развертывания, Catalina.jar и Tomcat-Coyote.jar в каталоге LIB в каталоге приложений Tomcat должны быть удалены. Например, каталог LIB Project-d:/workspace/websocket/webroot/web-inf/lib, а развернутый приложение Lib Directory-d: /tools/apache-tomcat-7.0.32/webapps/websocket/web-inf/lib. Просто удалите каталог LIB в каталоге развертывания и подключите две банки. В противном случае ошибка не может быть инициализирована. Помнить.
Если соединение все еще невозможно, пожалуйста, загрузите последнюю Tomcat. Забыл эту версию TomcatcreatewebSocketInbound, не имеет параметра запроса. Текущий код имеет этот параметр. Версии 7.0.3xx все поставляются с этим параметром, помните.
Суммировать
Использование WebSocket для разработки сервера очень удобно. Это простое приложение. На самом деле, это также может объединить WEBRTC, чтобы реализовать видеочат и голосовой чат.
Пример скачать
Адрес скачивания: Демо
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.