Отправлять уведомление от сервера к клиенту на сервере

Как отправить сообщение от сервера клиенту с помощью PHP, избегая посторонних вызовов Ajax.

Вот идея:

  • Пользователь: Алиса делает изменения, которые отправляются на сервер.

  • Затем сервер проверяет, какие пользователи не обновлены, и если он не вызывает какой-либо код для отправки информации, относящейся к изменению, к Бобу (который в этом случае не обновляется).

Как отправить сообщение Бобу?

Ответ 1

Вы можете использовать Server Sent Events.

Это часто выглядят кузеном из веб-карт, которые имеют более легкий вес и один способ. Они по существу позволяют клиенту ждать сообщения с сервера (который затем вы можете ответить через другой канал, такой как AJAX)

Пример кода клиента:

var source = new EventSource('/newFile');

source.addEventListener('message', function(e) {
  // Use AJAX and pull new file here
}, false);

Несомненно, кажется, что существует no поддержка IE. Можно использовать библиотеку, такую ​​как EventSource HQ для поддержки событий, переданных сервером с перекрестным браузером. Он будет абстрагироваться от необходимости обращаться с браузером дьявола.

Ответ 2

То, что вы ищете, является тем, что (сейчас) довольно распространено и иногда называется "веб-сайтом реального времени". Это возможность иметь ваш серверный код для распространения контента на подключенные клиенты, как это происходит, в режиме реального времени.

Это возможно благодаря нескольким новым механизмам, которые поддерживаются новейшими браузерами (и серверами) и некоторыми другими механизмами, которые на самом деле не предназначены для этого, но которые могут использоваться как "хаки", чтобы сделать это работа.

Первое, что вам нужно понять, это то, что вы просите (сервер "нажимает" сообщение клиенту) заключается не в том, как веб (или, по крайней мере, http) (или лучше) был предназначен работать. Классический веб-сайт является безстоящим, запрос-ответ, полудуплекс: клиент инициирует связь, открывает соединение с сервером, сервер обслуживает что-то, и соединение закрывается. И не было сервера для отправки сообщения веб-клиенту: клиент (т.е. Ваш браузер) должен поддерживать обратную модель (предлагая конечную точку, на которой он слушает), становясь фактически сервером.

Это более или менее то, что предлагают более новые стандарты, такие как WebSockets (еще один стандарт, на который стоит упомянуть Server-sent events (SSE), однако его поддержка еще сложнее, чем WebSockets, и они кажутся более склонными к "поточному" контенту, чем отправка отдельных сообщений).

В отличие от HTTP, WebSocket обеспечивает полнодуплексную связь (любая сторона может инициировать ее), что и есть то, что вы ищете. Правильная версия протокола WebSocket (более старая, некорректная реализация существует в некоторых браузерах) реализована в Firefox 6, Safari 6, Google Chrome 14, Opera 12.10 и Internet Explorer 10.

Итак, что, если ваш браузер не поддерживает WebSockets? Вы должны использовать те "трюки", о которых я упоминал ранее. Эти "трюки" подпадают под некрозон Push technologies.

В частности, общей методикой является длительный опрос. Как говорится в названии, это не "толчок"; длительный опрос - опрос, т.е. метод "тянуть", но он позволяет эмулировать механизм push. При длительном опросе клиент запрашивает информацию с сервера точно так же, как в обычном вызове AJAX, за исключением того, что он выдает свои HTTP/S запросы (опросы) на гораздо более медленной частоте.

После подключения сервер (ваш сервер, ваш API: сервлет, обработчик HTTP, REST-контроллер, что бы это ни было! Это, как правило, тот же механизм, с помощью которого вы предоставляете поддержку ваших стандартных вызовов AJAX) отправляет некоторую информацию, если есть уже уже доступно обновление; если нет ничего нового, вместо того, чтобы посылать пустой ответ, он удерживает запрос открытым и ожидает получения информации об ответах.

У вас есть "традиционный" запрос, инициированный клиентом, но он помещается "на удержание" до тех пор, пока сервер не захочет связаться с вами. После чего-то сервер отправляет клиенту ответ (через HTTP-канал, все еще открыт!), Завершая открытый HTTP-запрос.

Можно использовать другие методы (например, использование сокетов, предоставляемых плагинами - Silverlight, Java-апплеты, Flash..), но затем снова для использования им нужен правильный клиент (комбо-браузер/плагин).

Конечно, вы могли бы реализовать все эти вещи самостоятельно. И я призываю вас попробовать как учебное упражнение.

Для вашего производственного кода лучше использовать библиотеку, которая инкапсулирует все эти понятия и методы, например SignalR (для ASP.NET) Ratchet (для PHP), Signal.IO (для node.js), Faye (для Ruby).... В некоторых из этих библиотек будет реализовано более одного метода, выберите лучший техника, основанная на клиенте, автоматически возвращается к другим. Они действительно избавляют вас от многих неприятностей!

Ответ 3

Как было сказано в комментариях, технология, которую вы ищете, это WebSockets. Это способ, по которому у вас есть сокет (терминология unix lingo для существенной битрейтальной трубы) между вашим сервером и клиентом веб-браузера.

В то время как можно работать с необработанным websocket api. Я предпочитаю использовать библиотеку, например Socket.IO, чтобы отвлечь от меня неприятные данные.

После установки пакета как обычно (при условии, что вы используете node), Socket.IO предоставляет вам множество различных простых способов, таких как события и трансляции, которые интегрируются в ваше приложение. Вы также можете просто использовать его в качестве только кросс-браузера websocket (он реализует длительный опрос резервного копирования для браузеров, которые не поддерживают веб-сайты).

В вашем случае вы хотите отправить сообщение от сервера клиенту, когда на сервере будет изменен файл.

Одна сторона сервера (Node.js):

var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  socket.on('message', function () { });
  socket.on('disconnect', function () { });

  // more stuff here
  if(somethingChanged) {
    socket.send(JSON.stringify({changed: true, file: 'file1.txt', newContent: 'Im fresh off the press yo!'});
  }
});

Для клиента:

<script>
  var socket = io('http://localhost/');
  socket.on('connect', function () {
    socket.send('anything-new');

    socket.on('message', function (msg) {
      if(JSON.parse(msg).changed) {
        // Do stuff here
      }
    });
  });
</script>

Пока это очень простой пример, мы надеемся, что вы начнете.