задний планАвтор: большой ход
Данная статья является оригинальной статьей, просьба указывать автора и источник для перепечатки
Для поддержки функции просмотра живого видео CCtalk и чата в реальном времени на веб-сайте традиционные короткие соединения не могут достичь цели передачи в реальном времени, и необходимо установить длинное соединение.Однако стоимость установления соединения для веб-пользователей очень мало, а потребление ресурсов при длительном соединении велико, что требует от фреймворка достаточной поддержки большого параллелизма. Удовлетворяя большой параллелизм и поддерживая длинные соединения, Netty + Websocket является хорошим решением, поэтому я подробно представлю этот контент в трех статьях.
-
WebSocket
Резюме
В первых двух статьях были представлены принцип и применение соответственно, На этот раз я расскажу о применении WebSocket в Netty.
Что такое веб-сокет
Традиционный протокол HTTP может инициировать связь только на стороне клиента, но не может выполнять активное уведомление со стороны сервера. Некоторые здесь могут сказать, что можно использовать long polling, то есть клиент постоянно запрашивает сервер для получения новых данных.Это хоть и может решить проблему, но неэффективно и тратит ресурсы.Можно сказать, что это глупый способ. . Так появился WebSocket.
Протокол WebSocket родился в 2008 году и стал международным стандартом в 2011 году, поддерживаемым всеми браузерами. Его самой большой особенностью является полнодуплексная связь между сервером и клиентом, то есть клиент может активно отправлять сообщения серверу, а сервер также может активно отправлять сообщения клиенту.
Протокол по умолчанию использует порт 80 или 443, идентификатор протокола — ws (или wss, если он зашифрован), а URL-адрес сервера — это URL-адрес, например:
ws://example.com:8080/path
И HTTP, и Websocket построены на протоколе TCP, как показано ниже:
Отличие в том, что процесс взаимодействия с сервером отличается, как показано на следующем рисунке:
Как видно из рисунка, традиционный HTTP имеет только запросы и ответы, в то время как WebSocket делится на эти этапы.
-
рукопожатие
-
Клиент инициирует запрос установления связи со следующим сообщением:
Upgrade , Connection Эти две инструкции в настоящее время инициируются протоколом WebSocket.
Sec-WebSocket-Key — это значение кодировки Base64, которое случайным образом генерируется браузером для проверки того, поддерживает ли сервер протокол веб-сокета.
Sec_WebSocket-Protocol Это определяется пользователем в соответствии с бизнесом, который указан в URL-адресе.
-
Сервер отвечает на запрос рукопожатия следующим сообщением:
Sec-WebSocket-Accept Эта строка подтверждена сервером и зашифрована Sec-WebSocket-Key.
Видно, что на этапе рукопожатия используется протокол HTTP, который может проходить через различные прокси-серверы HTTP и имеет хорошую совместимость с протоколом HTTP.
-
длительный этап подключения
Обновлен с протокола HTTP на протокол Websocket через рукопожатие,
В это время вы можете отправить любое сообщение на сервер, и служба также может активно отправлять вам сообщения. Формат данных может быть согласован с сервером в соответствии с потребностями бизнеса, с высокой гибкостью и эффективной связью.
-
Соединение закрывается, когда один из клиента и сервера инициирует закрытие.
Приложение веб-сокета
В основном мы используем фреймворк Netty для реализации сервера и JS для реализации клиента.
Реализация сервера
В основном используется фреймворк с открытым исходным кодом Netty-socketio.На основе фреймворка Netty инкапсулированы анализ протокола и ответ WebSocket.Если вы являетесь проектом maven, вы можете добавить зависимость в pom.xml.
<dependency> <groupId>com.corundumstudio.socketio</groupId> <artifactId>netty-socketio</artifactId> <version>1.7.12</version></dependency>
скопировать код
Приложение относительно простое, следующий код:
public static void main( String[] args ) throws InterruptedException { final SocketIOServer server = new SocketIOServer(loadSocketIOConfig(doc)); // (1) // 启动login final SocketIONamespace ns = server.addNamespace("/echo"); // (2) EchoConnectListener listener = new EchoConnectListener(); // (3) EchoEventListener evtlistener = new EchoEventListener(); // (4) ns.addConnectListener(listener); ns.addDisconnectListener(listener); ns.addEventListener(WebEventMessage.EVT_TAG, WebEventMessage.class, evtlistener); // (5) server.start(); logger.info("============>WSServer started ... ok");}private static Configuration loadSocketIOConfig(Document doc) { Configuration config = new Configuration(); config.setHostname(getNodeStr(doc, "host")); config.setPort(getNodeInt(doc, "port")); config.setBossThreads(getNodeInt(doc, "bossThreads")); config.setWorkerThreads(getNodeInt(doc, "workerThreads")); //config.setUseLinuxNativeEpoll(PlatformDependent.isWindows() ? false : true); return config;}
скопировать код
public class EchoEventListener implements DataListener<WebEventMessage> {private static final Logger logger = LoggerFactory.getLogger(EchoEventListener.class); public EchoEventListener() { }@Override public void onData(SocketIOClient client, WebEventMessage data, AckRequest ackSender) throws Exception { System.out.println("message:" + data.getMessage()); WebEventMessage hello = new WebEventMessage(); JSONObject object = new JSONObject(data.getMessage()); if (UserTokenMgr.getInstance().verify(object.getInt("userid"), object.getString("token"))) { hello.setMessage("login success"); } else { hello.setMessage("login failed"); } client.getNamespace().getBroadcastOperations().sendEvent(WebEventMessage.EVT_TAG, hello); // (6) }}
скопировать код
Примечание. Арабские цифры в образце кода и арабские цифры в текстовом описании находятся во взаимно однозначном соответствии.
-
Загрузите конфигурацию, создайте экземпляр SocketIOServer, конфигурация в основном состоит из IP-адреса, порта, количества потоков обработки и рабочих потоков.
-
Добавьте пространство имен с именем echo, этот конкретный доступ отражается в URL-адресе следующим образом:
ws://example.com:8080/echo
Пока этот URL-адрес доступен, он будет обрабатываться в этом пространстве имен.
-
Создание прослушивателя соединения
-
Создание обработчика бизнес-сообщений
-
Добавьте прослушиватели соединений и обработчики бизнес-сообщений в пространство имен.При добавлении обработчиков бизнес-сообщений необходимо указать объект протокола сообщений, например WebEventMessage.
-
Сервер получает данные и возвращает их клиенту.
Реализация клиента
Здесь клиент использует socket.io, который реализован на JS и подключен к внешнему интерфейсу.
var socket = io.connect('http://127.0.0.1:8080/echo');socket.on('connect', function() { output('<span class="connect-msg">Client has connected to the server!</span>');}); // (1)socket.on('message', function(data) { output('<span class="username-msg"> echo' + ':</span> ' + data.message);}); // (2)socket.on('disconnect', function() { output('<span class="disconnect-msg">The client has disconnected!</span>');}); // (3)
скопировать код
отправить данные:
var message = JSON.stringify(jsonmsg);var cmd = 1;var jsonObject = {'@class': 'WebEventMessage', cmd:cmd, message: message}; socket.emit('message', jsonObject, function(arg1, arg2) {}); // (4)
скопировать код
Примечание. Арабские цифры в образце кода и арабские цифры в текстовом описании находятся во взаимно однозначном соответствии.
-
Функция обратного вызова после установления соединения.
-
сообщение используется для указания функции обратного вызова после получения данных сервера.
-
Функция обратного вызова после разъединения отключена.
-
emit отправляет сообщение на сервер.
Суммировать
Основанный на Netty Websocket, он обеспечивает хорошую производительность, но значительно расширяет возможности прямых трансляций, чатов и других продуктов на странице интерфейса. В настоящее время прямая трансляция CCtalk на веб-сайте и еще один разрабатываемый продукт используют эту технологию. Вы можете открыть ее.CCtalk (http://woowowoo.убедите его покинуть.com/)Веб-сайт Найдите класс в прямом эфире и посмотрите его. Эти три статьи в основном предназначены для того, чтобы бросить кирпичи в нефрит и предоставить решение.Если есть лучшее, или если у вас есть другие вопросы, пожалуйста, не стесняйтесь общаться.
Ссылка на ссылку
-
Sokect.io(HTTPS://сокет.IO/)
-
netty-socketio(https://GitHub.com/MryouKO/Netty-socket IO)
-
Учебник по веб-сокетам(HTTP://woo woo. Ruan Yifeng.com/blog/2017/05/Web socket.HTML)
Торговая система — Анализ проектирования на основе домена
Фреймворк краулеров на базе Electron Nightmare
Перевод | фильтры seccomp в Android O