2015-10-11 2 views
4

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

Вопрос: При использовании или кажется, что все еще происходит опрос. Это верно?

Пример(не реальный проект): Я хочу, чтобы держать глаза на текстовый файл. Если мне не хватает чего-то (больше кофе?), Мне все равно не нужно a) Спросите у сервера, есть ли обновление, или b) Сообщить о проблеме У меня есть обновление; Через спящий PHP-код на заданное время или с петлей setTimeout на стороне клиента.

Вещи, которые я понимаю: Я определенно вижу преимущество уже с разговором между сервером и страницей. Я вижу, что я не отправляю HTTP-запросы. Поэтому я вижу преимущества.

Детали: Я всегда просто использовали , так что я решил проверить это вся WebSockets вещь, как от того, что я думал, что я понял, является то, что данные передаются клиенту в режиме реального времени, но, как было сказано выше, если мне не хватает чего-то или какой-то логики здесь, мне кажется, что мне еще нужно либо сообщить , либо , чтобы проверять интервалы для данных, иначе данные отправляются в бесконечном цикле (представьте, что вы делаете вызов mysql).

Возможно, моя логика в моем коде - это все виды плохого. Вы можете просмотреть его. Из всех примеров, которые я нашел, все, кажется, просто запустить бесконечный цикл в PHP

PHP (минус все соединительного жаргоне)

while(true) { 
    // update once a second 
    $this->send($client, file_get_contents('/my/file/test.txt')); 
    sleep(1); 
} 

Javascript

var websocket = new WebSocket("ws://mysite.com:12345"); 

websocket.onmessage = function(str) { 
    console.log(str.data); 
}; 

Я просто не понимаю логику этого, как я могу сделать это в режиме реального времени без какого-либо опроса. Возможно, так оно и должно работать.

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

Редактировать: Чтобы уточнить, я специально не ищу конкретное решение для просмотра текстового файла. Возможно, вы подумали об этом, если у вас возник вопрос.

Редактировать: Будущие посетители, ответ на этот вопрос: вместо того, чтобы специально следить за изменениями, когда пользователь отправляет изменения, вы отправляете изменения для открытия соединений.

+0

Целью websocket/socket в общем случае является постоянное постоянное соединение, которое всегда открыто, поэтому в случае, если речь идет о программе чата. Клиенты получают данные, когда они доступны, они экономят пропускную способность, не имея для опроса/отправки на сервер каждые несколько секунд, чтобы показаться отзывчивым. Просто подождите и у вас получилось событие. Что касается мониторинга файла на стороне сервера, для этого требуется опрос. Но сервер сам опросит файл и отправит обновление всем клиентам, а не всем клиентам, проверяющим с сервером каждые несколько секунд, Websockets здесь все равно сэкономит вам пропускную способность. – Mayhem

+0

Я полностью понимаю цель websockets. Вопрос касается опроса нового контента и того, как работает эта логика. – Jesse

+0

Как уже говорилось, вы все равно будете локально проверять файл PHP, а затем уведомлять клиентов о том, когда обнаружено изменение, относительно того, как вы просматриваете файл. Это может различаться. Вы могли бы использовать задание CRON, но потребовали бы, чтобы сервер сокета работал на другом скрипте угроз/php. Возможно, используя http://php.net/manual/en/function.fam-monitor-file.php, но в остальном я будет просто иметь что-то вроде функции FAM, запущенной в основном цикле сервера сокета, если обнаружено, то отправить сообщение ко всем сообщениям. – Mayhem

ответ

0

Websockets позволяет избежать опроса вообще, если вы контролируете все события (или Sub/Pub для внешних событий).

Что касается вашего примера, если вы контролируете действие записи в файл, вы можете вызвать веб-расписание «трансляцию» или «опубликовать» это событие.

Таким образом, вы избегаете опроса вообще.

Поскольку я ненавижу работать с PHP (без обид, я просто заполнил его). Вот пример Ruby с использованием Plezi Real-Time Framework.

В этом примере мы используем простой способ touch для выполнения действия. Хотя я не очень трогаю файл, вы можете почувствовать, что использование API позволило мне управлять событием и транслировать другим пользователям. не участвует в опросе.

То же самое было бы верно, если бы я подписывался на внешние события.

Чтобы запустить этот пример, установите plezi камень с помощью [sudo] gem install plezi (в зависимости, если вам нужно sudo или нет и системы) и откройте IRB терминал с помощью команды irb с вашего терминала. Чем вставьте следующий код:

require 'plezi' 

class RootController 
    def index 
     %{<html><head> 
<script> 
    var websocket = NaN; 
    function connect() { websocket = new WebSocket((window.location.protocol.match(/https/) ? 'wws' : 'ws') + '://' + window.location.hostname + (window.location.port == '' ? '' : (':' + window.location.port)) + "/"); } 
    function init() 
    { 
     connect() 
     websocket.onopen = function(evt) { WriteMessage("(Connected and waiting for messages)", "connection") }; 
     websocket.onclose = function(evt) { WriteMessage("(Disconnected. messages will be lost)", "connection");connect(); }; 
     websocket.onmessage = function(evt) { 
      WriteMessage(evt.data, ""); 
     }; 
     websocket.onerror = function(evt) { WriteMessage(evt.data, 'error'); }; 
    } 
    function WriteMessage(message, message_type) 
    { 
     if (!message_type) message_type = 'received' 
     var msg = document.createElement("p"); 
     msg.className = message_type; 
     msg.innerHTML = message; 
     document.getElementById("output").appendChild(msg); 
    } 
    function Send(message) 
    { 
     WriteMessage(message, 'sent'); 
     websocket.send(message); 
    } 
    window.addEventListener("load", init, false); 
    </script></head> 
<body> 
<p>Messages should show up here:</p> 
<div id=output></div> 
</body> 
</html> 
     } 
    end 
    def touch 
     FileController.touch 
     "You Touched the file, a message should be sent to the web browser windows." 
    end 
    def on_message data 

    end 
    def self.push_update_event 
     RootController.broadcast :notify_client, "The file was updated." 
    end 
    protected 
    def notify_client data 
     response << data   
    end 
end 

class FileController 
    def self.touch 
     GR.info "A file should be touched" 
     puts "you can do whatever you feel like here..." 
     RootController.push_update_event 
    end 
end 

class APIController 
    def touched 
     RootController.push_update_event 
    end 
end 

listen 

route '/', RootController 
route '/api', APIController 

exit # the server will start once you exit the irb terminal 

Теперь посетить, в двух разных окнах браузера:

Или, вы можете даже "редактировать файл" (фактически) с использованием внешнего скрипта, а затем посетите http://localhost:3000/api/touched, чтобы сообщить всем пользователям об этом действии (аутентификация здесь не показана, но должна быть объявлена DED).

+1

Я получаю его сейчас. Спать на нем и видеть ваш ответ о посещении в двух окнах браузера. Полагаю, я думал об этом старомодный один пользователь за раз. Вместо просмотра изменений, когда один пользователь отправляет изменения, я обновляю все клиенты. Я знал, что думал об этом неправильно. – Jesse

-4

Здесь необходимо программирование на основе событий. Было бы намного проще использовать библиотеку, которая обрабатывает события для вас. PHP не лучший инструмент для такого типа программирования, но для него все еще может быть библиотека.

Одним из решений было бы иметь сервер nodejs/socket.io, и ваши php-процессы могли бы отправить ему сообщение, когда произойдет что-то интересное. Сервер nodejs затем передаст это вместе с клиентами.

+4

Я искренне надеялся, что не получим ответ узла js для вопроса не узла js. Я знаю об узле js, этот вопрос касается PHP, а не конкретно о библиотеках. В частности, речь идет о том, как работает опрос для нового контента, в PHP, нет библиотеки, а не в узле JS. Это больше подходит как комментарий – Jesse

+3

Я не могу утверждать, что все теперь указывает людям на node.js .. Создание сервера веб-сайтов на PHP простое, просто требуется, чтобы люди могли программировать и устанавливать другую чертову lib ... Python оказался моим выбором для сервера websocket в качестве большего контроля и меньших ресурсов, необходимых для этого. – Mayhem

+3

@ Майем - Я не мог больше согласиться. Это похоже на вопрос Javascript, где первый ответ: «Вы должны использовать jquery». – Jesse

0

Я бы предложил что-то похожее на это изначально.

$sFile = "/my/file/test.txt"; 
$timeMod = filemtime($sFile); 
while(true) { 
    if (filemtime("SomeFileHere.txt")!==$timeMod) { 
     $timeMod = filemtime($sFile); 
     // File has changed, update variable with new timestamp 
     $this->send($client, file_get_contents($sFile)); 
    } else { 
     // No change, do nothing here. 
    } 
    sleep(1); 
} 

В основном перед вами циклом, вы получите дату последнего изменения .. Если в цикле она изменилась, мы обновляем переменные и отправить уведомление в то время.

Если вы пытаетесь сделать что-то похожее на эту работу в реальном мире без каких-либо проблем с загрузкой, у меня будет один PHP-файл, работающий в цикле (возможно, dameon) .. Который будет отслеживать файл каждую секунду в простом цикле, например выше .. Если есть изменение, я хотел бы, чтобы он уведомил другой PHP-скрипт/поток для отправки контента всем клиентам.

Если один и тот же файл отправляется всем клиентам, это не будет плохо. Как вы можете использовать функцию отправки ко всем функциям. Но если она отличается от каждого клиента (например, их собственной истории/журнала). требуется обработка на одного клиента, который будет немного поражен.

Для дальнейшего последующего доказательства такого материала вы записываете время, когда клиент последний раз получил содержимое файла и ограничил, как долго он может быть отправлен снова .. Таким образом, клиент получает новую копию через 10 секунд мин. , ничего меньше, и он просто игнорирует.

В какой сфере/масштабе & Тип проекта - это?

В настоящее время мой сервер python может получить запрос от 20 000 клиентов и обработать их данные и ответить обратно в течение одной секунды ... (GPS-обработка). Хотя я не отправляю ничего за килобайт каждый раз, возможность потоковой передачи и очереди в python сделает его гораздо более удобным и может обрабатывать множество клиентов в одном экземпляре. с использованием только около 130 МБ оперативной памяти без утечек памяти с течением времени

PHP, который, как мне кажется, не должен работать вечно в цикле, просто не хочется, как его использовать.

+0

Полностью правильный способ решения этого вопроса с помощью моего примера (это работает только в примере, который не является реальной задачей, которую я пытаюсь выполнить, это всего лишь пример). Я не думаю, что вы полностью понимаете вопрос, могу ли я быть честным. – Jesse

+0

Объясните подробнее? не на том же уровне atm – Mayhem

+0

Я не ищу конкретное решение для просмотра текстового файла. – Jesse

Смежные вопросы