Websockets PHP / AJAX / Javascript 刷新客户端

Posted

技术标签:

【中文标题】Websockets PHP / AJAX / Javascript 刷新客户端【英文标题】:Websockets PHP / AJAX / Javascript refresh client 【发布时间】:2014-06-20 06:36:54 【问题描述】:

我正在使用带有 php 和一些 javascript 的 websockets。我将数据库中的一些信息显示给我的客户。我的目标是当信息插入我的数据库时刷新客户端。为了在我的数据库中插入一些数据,我从我的 PC 发送了一个发布请求。

目前,我可以每 10 秒刷新一次客户端以调用一个函数。但我只想在该页面上发送 POST 请求时刷新。

这里有一些东西可以帮助你理解:

    客户端正在连接到网页。 在我的数据库上执行 SQL 选择 结果被接收并显示在网页上。 客户端已连接(通过 websockets)并查看数据库中的信息。 我。如果我在数据库中插入信息,我会发送一个 POST 请求(不是来自 html 表单,没有提交,只是一个 POST 请求,就像我使用 Postman 测试 Web 服务一样)。发送请求时,通过调用 Javascript 函数刷新客户端...

这是我所做的:

index.php(显示信息的页面)

$(document).ready(function()

    //create a new WebSocket object.
    var wsUri = "ws://localhost:9000/server.php";
    websocket = new WebSocket(wsUri);

    websocket.onopen = function(ev)  // connection is open
        $('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user
    

    // Call this function every 10 sec to refresh the client
    window.setInterval(function()
        displayInfo(1);
    , 10000);

    websocket.onmessage = function(ev) 
        var msg = JSON.parse(ev.data); //PHP sends Json data
        $("#infos").html(msg.message);
    ;

    websocket.onerror   = function(ev)$('#message_box').append("<div class=\"system_error\">Error Occurred - "+ev.data+"</div>");;
    websocket.onclose   = function(ev)$('#message_box').append("<div class=\"system_msg\">Connection Closed</div>");;
);

function displayInfo(r) 

    $.post("infos.php",
         refresh : r,
        function(data)

            var msg = 
                message: data
            ;

            //convert and send data to server
            websocket.send(JSON.stringify(msg));
        
    );

infos.php:我执行 SQL 选择请求的位置(工作正常)

server.php :服务器端的代码在哪里。 (工作正常)

嗯。我真的不知道我怎么能做到这一点。如何通知和调用函数displayInfo(r);如果一个 POST 请求被发送到这个页面。

非常感谢任何帮助。提前谢谢你。

问候, 拉皮努。

【问题讨论】:

你应该在这里找到一些好的提示:dsheiko.com/weblog/websockets-vs-sse-vs-long-polling 你用什么PHP库来做websocket服务器? @sdespont - 谢谢!我今天会检查这个教程! @JohnKiller - 我并没有真正使用图书馆。我已经按照本教程进行操作:sanwebe.com/2013/05/chat-using-websocket-php-socket 【参考方案1】:

我从您提供的链接中看到了server.php,它很简单:

    接受传入连接 循环通过所有连接的套接字 如果这些套接字中的任何一个有数据,它就会回复所有其他客户端。

您需要更改此循环并添加另一个消息来源,您有 2 个选项。您可以汇集一个 DB 或打开另一个 TCP 套接字并从那里读取。

然而,最好的解决方案是将 NodeJS 与 Socket.io 和 DNode 一起使用(非常优雅的解决方案,可以跨浏览器工作,而且并不难),但是您需要能够在服务器上安装 NodeJS。如果你愿意,我可以提供样品。


编辑:这就是我的做法。

我假设您熟悉基于 Debian 的发行版(我将使用 APT 进行安装)。首先我会解释一些事情:

NodeJS 是一个服务器端 javascript 解释器,它将运行我们的套接字部分。事实上,我们会同时使用 PHP 和 NodeJS(后者仅用于更新客户端,因此您现有的代码不会有太大变化) NPM 是一个命令行实用程序(NodeJS 附带)。它的主要用途是安装包(Socket.io 和 DNode 是 NPM 包) Socket.io 是 WebSockets 的包装器,使其可以跨浏览器工作。它还包含服务器端处理函数 DNode 是用于与其他语言/服务器通信的 RPC(在本例中,使用我们的 PHP 脚本)

首先我们安装 NodeJS。 Ubuntu repo 上的版本太旧了,所以我们从here 添加一个 PPA:

sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install node

这将安装 NodeJS 和 NPM。更多信息here.

现在 cd 进入您的工作目录并创建此文件:server.js

//import libraries
var io = require('socket.io');
var dnode = require('dnode');

var clients = []; //this array will hold all connected clients

var srv = io.listen(8080,  log: false ); //this port must be different from apache
srv.sockets.on('connection', function(socket)
    console.log("Client connected.");
    clients.push(socket);

    //this will be called when a javascript client sends us something. you can delete this if you don't need it
    socket.on('message', function(data)
        console.log(data); 
    );

    socket.on('disconnect', function()
        console.log("Lost client.");
        var i = clients.indexOf(socket);
        clients.splice(i, 1); //remove from array
    );
);

var dnode_server = dnode(
    //expose a "send" function
    send: function(data, cb)
        for(i = 0; i < clients.length; i++)
            clients[i].emit('update',  //send an "update" message to all connected clients
                title: data.title, //some data
                text: data.text
            );
        
        cb(null, false); //inform PHP that the processing is done. You can also return something
    
    //you can have multiple functions here
);
dnode_server.listen(5004); //this port should not be accessible from the ouside

接下来,安装所需的库:

npm install socket.io
npm install dnode

您可以使用node server.js 运行此脚本

现在我们需要编辑客户端 javascript。使用这个导入 Socket.io:

<script type="text/javascript" src="http://YOURHOSTNAME:SOCKETIOPORT/socket.io/socket.io.js"></script>

然后像这样使用它:

socket = io.connect('http://YOURHOSTNAME:SOCKETIOPORT');
socket.on('connect', function(data)
    alert('Connected!');
);
socket.on('disconnect', function()
    alert('Disconnected :( are you offline?');
);
socket.on('update', function(data) //our function call
    alert(data.title + " " + data.text);
);

您可以像在 NodeJS 上一样向服务器发送数据:

socket.emit('message', foo: 'bar');

最后,您想通过 PHP 脚本在所有连接的客户端上触发“更新”。为此,我们需要一个用于连接 DNode 的 PHP 库。可以找到here,用法很简单:

$dnode = new \DnodeSyncClient\Dnode();
$connection = $dnode->connect('localhost', 5004);
$connection->call('send', array(array(
    'title' => "My awesome title",
    'text' => "My awesome text"
)));

调用此 PHP 脚本会将标题和文本发送到您的 server.js,然后将所有内容广播到您连接的客户端。

希望这会有所帮助!

【讨论】:

感谢 JohnKiller 提供此信息!我以前从未使用过 NodeJS。我不会打扰你,但如果你有时间样品,为什么不:)。再次感谢您! 没问题,如果您有任何问题,请告诉我 :)

以上是关于Websockets PHP / AJAX / Javascript 刷新客户端的主要内容,如果未能解决你的问题,请参考以下文章

json刷新没有ajax,websockets

PHP 共享主机上的 WebSockets

SSE 或 Websockets 或 AJAX - 服务器负载

POST 到 PHP 与服务器发送的事件?

通过 Websockets + NodeJS 而不是 AJAX 加载 Jade -> HTML

我可以将 HTML5 WebSockets 用于通常使用 AJAX 完成的任务吗?