当我收到新电子邮件时,让网站发出通知

时间:2013-06-02 23:54:58

标签: php web

我正在尝试构建一个网页,我可以在浏览器中打开并保持打开状态。

如果我打开页面时收到电子邮件,我希望网页发出噪音,更具体地说是吹气号。

我已经构建了一个php脚本,我可以从我的计算机上运行,​​它将检查我的收件箱中是否有新邮件,如果有新邮件则播放.mp3文件。我想将此功能从我在计算机上运行的脚本转换为任何人都可以访问的网页(这样他们也可以听到计算机上的噪音)。

我的猜测是它应该实现的方式是这样的:php脚本每分钟都在cronjob上运行在服务器上。如果它检测到新的电子邮件,则有人会向网页发送一个信号,让所有在浏览器上查看的人都会发出声音。我不知道整个“信号”的东西如何起作用......

但也许不是这样做的方式。

我只需要了解一下基础知识是什么以及我应该如何将它们组合在一起。

2 个答案:

答案 0 :(得分:1)

我认为,最优雅的方法是使用Server-Sent Events进行服务器到客户端的通信,使用ZeroMQ进行cron脚本到网络服务器的通信。

先决条件: ZeroMQ PHP binding

cron调用的PHP脚本应通过发布事件来通知新电子邮件。由于the ZeroMQ guide中讨论的缓慢的细木工问题,我们会睡一会儿。可能有一种更优雅的方式来解决它,但它应该适合你:

$ctx = new ZMQContext();
$socket = $ctx->socket(ZMQ::SOCKET_PUB);
$socket->bind("tcp://127.0.0.1:50050");  // change the port if desired
sleep(1);
$socket->send("new message");

所以这很简单。接下来要做的是为服务器发送事件创建端点。幸运的是,该协议非常简单:我们使用text/event-stream MIME类型并发送如下所示的消息:

data: some data associated with the message

您还可以提供data以外的某些属性,包括eventidretry。您可以在the specificationthis tutorial中了解更多信息。

我们的端点将订阅新的消息事件,然后发回消息。我们可以为每个连接发送多条消息,但我会将其作为练习留给读者。 (提示:环绕recv / echo循环。):

header("Content-Type: text/event-stream");
flush();

$ctx = new ZMQContext();
$socket = $ctx->socket(ZMQ::SOCKET_SUB);
$socket->connect("tcp://127.0.0.1:50050");
$socket->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, "new message");

$event = $socket->recv();
echo "data: $event\r\n\r\n";
flush();

这是三个中的两个。最后,您需要一些JavaScript。在客户端使用服务器发送事件非常简单:

var eventSource = new EventSource("endpoint.php");
eventSource.onmessage = function(e) {
    // data field in e.data
    // frankly, we don't care; any message will be "new message"
    // play your sound in here
};

您可以使用HTML5 audio播放音频,使其变得如此简单:

var audio = new Audio();
audio.src = "airhorn.mp3";
var eventSource = new EventSource("endpoint.php");
eventSource.onmessage = function(e) {
    audio.currentTime = 0;  // rewind
    audio.play();
};

锻炼

  • (硬)删除sleep并将其替换为针对慢速木匠问题的更优雅的解决方案。

  • (简单)使端点能够在连接期间发送多条消息。

  • 连接关闭或删除时,
  • (中) EventSource将自动重新连接。在此期间,不会发送任何活动。要允许服务传递任何错过的消息,EventSource会向Last-Event-ID标头发送最后一条消息的id的值。如果在此期间发送了电子邮件,即使重新连接,也不会播放声音。修改代码,以便在重新连接后播放声音。 (提示:使用时间戳作为ID;使cron脚本存储文件中最后一个事件的时间戳;让端点查询该文件。)

进一步阅读

答案 1 :(得分:0)

我建议你运行你的cronjob并将结果(email_received = true / false)存储在mysql(或最坏情况场景文本文件)中。 然后创建另一个检查email_received值的脚本,将email_received更新为false(如果收到电子邮件,则不想再多次播放声音)并输出1或0。

最后创建一个网页(即使它是HTML),定期(每30秒)进行一次AJAX调用(可能使用jQuery)。如果AJAX请求返回1然后播放声音,否则什么都不做。

示例jQuery代码:

$(document).ready(function(){

setInterval(function(){
   $.get('/check_email.php', function(response) {
       if(response == 1){
          //play sound
       }
   });
},30000); //30 seconds

});