Ниже приведены резюме Ширен Яхуи в качестве справочного исследования.
Традиционный опрос
Распространенный метод непрерывной связи в современных веб-приложениях, обычно реализуемый с помощью setInterval или setTimeout. Например, если мы хотим регулярно получать и обновлять данные на странице, мы можем написать следующую реализацию в сочетании с Ajax:
setInterval(function() {
$.get("/path/to/server", function(data, status) {
console.log(data);
});
}, 10000);
Вышеупомянутая программа будет запрашивать данные с сервера каждые 10 секунд и сохранять данные по мере их поступления. Такой способ реализации, как правило, удовлетворяет простым требованиям, но в то же время имеет и большие недостатки: в случае нестабильных сетевых условий общее время от приема запроса сервером до отправки запроса клиенту, принимающему запрос, может превышать 10 секунд. Запрос отправляется с 10-секундными интервалами, что приведет к получению полученных данных в порядке, несовместимом с порядком отправки. Итак, есть метод опроса с использованием setTimeout:
function poll() {
setTimeout(function() {
$.get("/path/to/server", function(data, status) {
console.log(data);
// 发起下一次请求
poll();
});
}, 10000);
}
Программа сначала устанавливает запрос, который будет инициирован через 10 секунд, а затем инициирует второй запрос каждые 10 секунд после возврата данных и так далее. В этом случае, хотя интервал времени между двумя запросами не может быть фиксированным значением, можно гарантировать порядок поступления данных.
дефект
Программа создает новый HTTP-запрос для каждого запроса, но не каждый раз, когда возвращает нужные ей новые данные. Когда определенное количество запросов инициируется одновременно, на сервер будет возложена большая нагрузка.
длинный опрос
После того, как клиент отправляет запрос, сервер получает соединение и, если есть сообщение, возвращает ответ клиенту. Если сообщения нет, ответ не возвращается. После этого клиент снова отправляет запрос, повторяя последнее действие.
Суммировать
Отличительной чертой протокола http является то, что сервер не может активно связываться с клиентом и может быть инициирован только клиентом. Его пассивный характер указывает на то, что, когда двусторонняя связь завершена, соединение необходимо держать открытым или соединение всегда открыто, что требует высокой скорости обработки или высокого параллелизма сервера, что очень ресурсоемко.
Что такое вебсокет?
Websocket — это новый протокол HTML5, который позволяет серверу передавать информацию клиенту и реализует дуплексную связь между браузером и клиентом.
сказка
Потому что у протокола HTTP есть изъян: связь может инициировать только клиент. Например, если мы хотим узнать сегодняшнюю погоду, мы можем только сделать запрос от клиента к серверу, и сервер вернет результат запроса. Протокол HTTP не может позволить серверу активно передавать информацию клиенту. Характеристики этого одностороннего запроса обречены быть очень неприятными для клиента, чтобы узнать, есть ли у сервера непрерывные изменения состояния. Мы можем использовать только "опрос": время от времени выдается запрос. Опрос неэффективен и тратит ресурсы (потому что соединение должно поддерживаться постоянно, или соединение HTTP всегда открыто). Поэтому инженеры задумались, а есть ли способ лучше. Так был изобретен WebSocket.
Особенности веб-сокета
Сервер может активно передавать информацию клиенту, а клиент также может активно отправлять информацию серверу.Это настоящий двусторонний равноправный диалог и относится к разновидности серверной технологии push.
- Он имеет хорошую совместимость с протоколом HTTP. Порты по умолчанию также 80 и 443, а протокол HTTP используется на этапе рукопожатия, поэтому его нелегко экранировать во время рукопожатия, и он может проходить через различные прокси-серверы HTTP.
- Основанный на протоколе TCP, он относится к прикладному уровню как протокол http.
- Формат данных относительно легкий, производительность невелика, а связь эффективна.
- Текст может быть отправлен, или двоичные данные могут быть отправлены.
- Нет ограничений на одно и то же происхождение, клиенты могут связываться с любым сервером
- Идентификатор протокола — ws (или wss, если он зашифрован), а URL-адрес сервера — это URL-адрес, например, ws://localhost:8023.
Кроссплатформенная коммуникационная библиотека WebSocket socket.io
Кроссплатформенная коммуникационная библиотека WebSocket с согласованными интерфейсными и внутренними API, которые могут запускать пользовательские события и реагировать на них. Два основных API-интерфейса socket.io — emit и on .И сервер, и клиент имеют эти два API. Двусторонняя связь между сервером и клиентом может быть достигнута посредством отправки и включения.
- emit : генерировать событие, первый параметр — имя события, второй параметр — данные для отправки, а третий параметр — функция обратного вызова (если другой стороне необходимо получить подтверждение сразу после получения информации, функция обратного вызова необходимо использовать).
- on : прослушивание события, созданного с помощью emit, первый параметр — это имя события, которое нужно отслеживать, второй параметр — это функция обратного вызова, которая используется для получения данных, отправленных другой стороной, и первый параметр этого функция - полученные данные.
Сервер
var app = require('express')();
var http = require('http');
var socketio = require("socket.io");
const server = http.createServer(app)
const io = socketio(server)
var count = 0;
// WebSocket 连接服务器
io.on('connection', (socket)=> {
//// 所有的事件触发响应都写在这里
setInterval(()=>{
count++
//向建立该连接的客户端发送消息
socket.emit('mynameEv', { name:"你我贷"+count})
},1000)
//监听客户端发送信息
socket.on('yournameEv', function (data) {
console.log(data)
})
})
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
// 启用3000端口
server.listen(3000)
клиент
<body>
<div id="myname"></div>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var count = 0;
const socket = io.connect('http://localhost:3000')
socket.on('mynameEv', (data)=>{
document.getElementById("myname").innerHTML = data.name;
console.log(data.name)
setInterval(()=>{
count++
socket.emit('yournameEv', { name:"飞旋"+count})
},1000)
})
</script>
</body>