2014-06-22 159 views
11

我怎麼能發送郵件從服務器到客戶端,使用PHP,避免多餘的Ajax調用。從服務器發送通知到客戶端服務器上的事件

這裏的理念是:

  1. 用戶:愛麗絲使得它被髮送到服務器的變化。

  2. 服務器然後檢查以查看哪些用戶不是最新的,並且如果沒有調用一些代碼以將關於該改變的信息發送給Bob(在這種情況下誰不是最新的)。

如何向Bob發送消息?

+2

如果您對Stack Exchange使用的確切工具和技術感興趣,那麼[Meta Stack Exchange上的這個問題](http://meta.stackexchange.com/questions/10369/which-tools-and-technologies-被用來建立堆棧交換網絡)將對你有用。就實際實現具有類似功能的東西而言,這個問題太廣泛了。 – animuson

+0

調查[Ajax](https://en.wikipedia.org/wiki/Ajax_(programming))。 –

+2

@MthethewStrawbridge閱讀文章,我談論爲什麼這是行不通的。 – user3765372

回答

17

您可以使用Server Sent Events

這些都是重量更輕,單向的websockets常常看起來表兄弟。他們基本上是允許客戶端等待來自服務器的消息

示例客戶端代碼(然後你就可以通過不同的渠道,如AJAX迴應):

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

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

Unfortuantely看來(當然)那有no IE support。可以使用庫如EventSource HQ來支持跨瀏覽器服務器發送的事件。它會抽象出需要處理魔鬼的瀏覽器。

+0

Polyfills for http://www.w3.org/TR/eventsource/ - https://github.com/Yaffle/EventSource&https://github.com/remy/polyfills/blob/master/EventSource.js。當然,除IE之外,上面的這些作品還不多。 – user3257644

8

正如在評論中,你正在尋找的技術是WebSockets說。它們是您在服務器和Web瀏覽客戶端之間安裝套接字(一種用於必需的雙向管道的unix術語)的一種方式。

儘管人們可以用生的WebSocket API工作。我更喜歡使用像Socket.IO這樣的圖書館來爲我抽象出令人討厭的細節。

在通常情況下(假設您使用節點)安裝包後Socket.IO爲您提供了許多不同的簡單方法,例如事件和廣播集成到您的應用程序中。你也可以使用它作爲一個just a cross browser websocket(它實現回退長輪詢不支持WebSockets的瀏覽器)。

對於您的情況,您希望在服務器上更改文件時,將消息從服​​務器發送到客戶端。

一個服務器端(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> 

雖然這是一個非常裸露的例子是希望足以讓你開始。

13

您正在尋找的東西是(現在)很常見的東西,有時稱爲「實時網絡」。這就是讓您的服務器端代碼實時向連接的客戶端推送內容的能力。

這可以通過一些新的機制來實現,這些機制是由最新的瀏覽器(和服務器)支持的,還有一些其他的機制並不是真正被設計成這樣做的,但它可以被用作「黑客」這行得通。

你必須明白的第一件事是,你所要求的(服務器將消息推送到客戶端)並不是網絡(或至少http)是(或更好的))打算工作。 經典網頁是無狀態的請求響應半雙工:客戶端啓動通信,打開與服務器的連接,服務器提供服務,連接關閉。 以前沒有辦法讓服務器向Web客戶端發送消息:客戶端(即您的瀏覽器)應該支持反向模型(提供它所監聽的端點),從而成爲服務器。

這是,或多或少,什麼樣的WebSockets報價較新的標準(另一種標準值得一提的是Server-sent events (SSE);但是,它支持比WebSockets的更是鳳毛麟角,他們似乎更傾向於以「流」的內容不是發送單個消息) 。

與HTTP不同,WebSocket提供了全雙工通信(任何一方都可以啓動它),這正是您正在尋找的。 WebSocket協議(舊的,馬車在執行某些瀏覽器存在)的正確版本的Firefox 6,Safari瀏覽器6,谷歌Chrome 14,歌劇12.10和Internet Explorer 10

所以,如果你的瀏覽器不實施不支持WebSockets?你必須使用我前面提到的那些「技巧」。那些「詭計」屬於Push technologies的unbrella。

特別是,一種常用的技術是長輪詢。 就像名字所說,它不是「推」的;長輪詢是輪詢,即「拉」技術,但它允許模擬推送機制。 通過長時間輪詢,客戶端可以像在普通的AJAX調用中一樣請求服務器的信息,除了它以慢得多的頻率發出HTTP/S請求(輪詢)。在連接時,服務器(你的服務器,你的API:一個servlet,一個HTTP處理程序,一個REST控制器,無論如何!它通常與你提供對標準AJAX調用的支持相同的機制)發送一些信息if已經有可用的更新;如果沒有新的東西,而不是發送空的響應,它將保持請求打開並等待響應信息變爲可用。

您有一個「傳統的」客戶端啓動的請求,但這是「擱置」,直到有一些服務器想與您通信。 一旦出現問題,服務器會向客戶端發送響應(通過HTTP通道,仍然打開!),完成打開的HTTP請求。

可以使用其他技術(例如使用由插件提供的套接字--Silverlight,Java applets,Flash ..),但是爲了利用它們,您需要正確的客戶端(瀏覽器/插件組合)。

當然,你可以自己實現所有這些東西。我鼓勵你試試作爲學習練習。 (對於ASP.NET)Ratchet(對於PHP),Signal.IO(對於節點。)對於您的生產代碼,最好使用封裝所有這些概念和技術的庫,如SignalR(用於ASP.NET)Ratchet(用於PHP),Signal.IOjs),Faye(用於Ruby)....這些庫中的一些將實現多種技術,根據客戶端選擇最佳技術,自動回退到其他技術。他們真的給你帶來了很多麻煩!

相關問題