Websockets PHP / AJAX / Javascript刷新客户端

时间:2021-03-20 02:57:58

I'm using websockets with PHP and some Javascript. I display some information from my database to my client. My goal is to refresh the client when an information has insert into my database. To insert some data in my database, I send a post request from my PC.

我用的是websockets和PHP以及一些Javascript。我将数据库中的一些信息显示给客户。我的目标是在信息插入到数据库时刷新客户端。为了在我的数据库中插入一些数据,我从我的PC上发送一个post请求。

At the moment, I can refresh the client to call a function every 10 seconds. But I would like to refresh only if, on that page, a POST request is send.

现在,我可以刷新客户端每10秒调用一个函数。但是,我希望只有在这个页面上发送一个POST请求时才刷新。

Here is something that can help you to understand:

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

Websockets PHP / AJAX / Javascript刷新客户端

  1. The client's connecting to the web page.
  2. 客户端正在连接到web页面。
  3. A SQL select is execute on my database
  4. SQL select将在我的数据库上执行
  5. The result is received and displayed on the web page.
  6. 结果被接收并显示在web页面上。
  7. The client is connected (via websockets) and see the information from the database.
  8. 客户端被连接(通过websockets)并从数据库中查看信息。
  9. Me. If I insert an information on the database, I send a POST request (not from a HTML form, no submit, just a POST request, like if I used Postman to test a webservice). When the request is send, refresh the client by calling a Javascript function...
  10. 我。如果我在数据库中插入一个信息,我发送一个POST请求(不是来自HTML表单,不提交,只是一个POST请求,就像我用Postman测试一个webservice)。当请求发送时,通过调用一个Javascript函数来刷新客户机…

Here is what I've done:

以下是我所做的:

  • index.php (Page where the information are displayed)

    索引。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 : Where I execute the SQL select request (works fine)

    信息。php:在其中执行SQL select请求(运行良好)

  • server.php : Where the code for the server side is. (works fine)

    服务器。php:服务器端的代码在哪里。(没问题)

Well. I really don't know how can I achieve this. How to inform and call the function displayInfo(r); if a POST request is send to this page.

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

Any help is very appriciated. Thank you in advance.

任何帮助都是非常昂贵的。提前谢谢你。

Regards, Lapinou.

问候,Lapinou。

1 个解决方案

#1


8  

I've seen the server.php from the link you've provided, and it simply:

我看到服务器。php从您提供的链接,它只是:

  1. Accepts incoming connections
  2. 接受传入的连接
  3. Loops through all connected sockets
  4. 循环通过所有连接的套接字
  5. If any of these sockets has data, it replies to every other client.
  6. 如果这些套接字中有任何一个具有数据,那么它将响应所有其他客户机。

You need to alter this loop and add another source for messages, and you have 2 options. You can pool a DB or open another TCP socket and read from there.

您需要修改此循环并为消息添加另一个源,您有两个选项。您可以共享一个DB或打开另一个TCP套接字并从那里读取。

However, the best solution is to use NodeJS with Socket.io and DNode (very elegant solution that works cross-browser and is not that difficult), but you need to be able to install NodeJS on your server. I can provide samples if you want.

但是,最好的解决方案是使用带有套接字的NodeJS。io和DNode(非常优雅的解决方案,可以跨浏览器工作,没有那么困难),但是您需要能够在服务器上安装NodeJS。如果你需要的话,我可以提供样品。


EDIT: Here it goes my way of doing it.

I'll assume you are familiar with Debian based distributions (I'm going to install things with APT). First I'll explain some things:

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

  • NodeJS is a server-side javascript interpreter that will run our socket part. In fact, we will use both PHP and NodeJS (the latter only for updating clients, so your existing code will not change much)
  • NodeJS是一个服务器端javascript解释器,它将运行我们的套接字部分。事实上,我们将同时使用PHP和NodeJS(后者仅用于更新客户机,因此现有代码不会有太大变化)
  • NPM is a command line utility (that comes with NodeJS). Its main purpose is for installing packages (Socket.io and DNode are NPM packages)
  • NPM是一个命令行实用程序(NodeJS附带)。它的主要用途是安装包(套接字)。io和DNode是NPM包)
  • Socket.io is a wrapper around WebSockets that make it works cross-browser. It also contains the server-side handling functions
  • 套接字。io是一个围绕WebSockets的包装,它可以跨浏览器工作。它还包含服务器端处理函数。
  • DNode is an RPC for communicating with other languages/servers (in this case, with our PHP script)
  • DNode是一个用于与其他语言/服务器通信的RPC(在本例中,使用PHP脚本)

First we install NodeJS. The version on Ubuntu repo's is veeery old, so we add a PPA from here:

首先我们安装NodeJS。Ubuntu repo的版本非常古老,所以我们从这里添加了一个PPA:

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

This will install NodeJS and NPM. More info here.

这将安装NodeJS和NPM。更多的信息在这里。

Now cd into your working directory and create this file: server.js

现在,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

Next, install required libraries:

接下来,安装所需的库:

npm install socket.io
npm install dnode

You can run this script using node server.js

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

Now we need to edit the clientside javascript. Import Socket.io using this:

现在我们需要编辑clientside javascript。进口套接字。io使用:

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

Then use it like this:

然后像这样使用:

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);
});

You can send data to server like on NodeJS:

您可以像NodeJS一样将数据发送到服务器:

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

Finally, you want to trigger "update" on all connected clients from a PHP script. For this, we need a PHP library for interfacing DNode. You can find it here and its usage is very simple:

最后,您希望在PHP脚本中触发所有连接的客户机上的“更新”。为此,我们需要一个PHP库来与DNode交互。你可以在这里找到它,它的用法非常简单:

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

Calling this PHP script will send title and text to your server.js that will broadcast everything to your connected clients.

调用这个PHP脚本将向服务器发送标题和文本。将所有内容广播到连接的客户端。

Hope this helps!

希望这可以帮助!

#1


8  

I've seen the server.php from the link you've provided, and it simply:

我看到服务器。php从您提供的链接,它只是:

  1. Accepts incoming connections
  2. 接受传入的连接
  3. Loops through all connected sockets
  4. 循环通过所有连接的套接字
  5. If any of these sockets has data, it replies to every other client.
  6. 如果这些套接字中有任何一个具有数据,那么它将响应所有其他客户机。

You need to alter this loop and add another source for messages, and you have 2 options. You can pool a DB or open another TCP socket and read from there.

您需要修改此循环并为消息添加另一个源,您有两个选项。您可以共享一个DB或打开另一个TCP套接字并从那里读取。

However, the best solution is to use NodeJS with Socket.io and DNode (very elegant solution that works cross-browser and is not that difficult), but you need to be able to install NodeJS on your server. I can provide samples if you want.

但是,最好的解决方案是使用带有套接字的NodeJS。io和DNode(非常优雅的解决方案,可以跨浏览器工作,没有那么困难),但是您需要能够在服务器上安装NodeJS。如果你需要的话,我可以提供样品。


EDIT: Here it goes my way of doing it.

I'll assume you are familiar with Debian based distributions (I'm going to install things with APT). First I'll explain some things:

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

  • NodeJS is a server-side javascript interpreter that will run our socket part. In fact, we will use both PHP and NodeJS (the latter only for updating clients, so your existing code will not change much)
  • NodeJS是一个服务器端javascript解释器,它将运行我们的套接字部分。事实上,我们将同时使用PHP和NodeJS(后者仅用于更新客户机,因此现有代码不会有太大变化)
  • NPM is a command line utility (that comes with NodeJS). Its main purpose is for installing packages (Socket.io and DNode are NPM packages)
  • NPM是一个命令行实用程序(NodeJS附带)。它的主要用途是安装包(套接字)。io和DNode是NPM包)
  • Socket.io is a wrapper around WebSockets that make it works cross-browser. It also contains the server-side handling functions
  • 套接字。io是一个围绕WebSockets的包装,它可以跨浏览器工作。它还包含服务器端处理函数。
  • DNode is an RPC for communicating with other languages/servers (in this case, with our PHP script)
  • DNode是一个用于与其他语言/服务器通信的RPC(在本例中,使用PHP脚本)

First we install NodeJS. The version on Ubuntu repo's is veeery old, so we add a PPA from here:

首先我们安装NodeJS。Ubuntu repo的版本非常古老,所以我们从这里添加了一个PPA:

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

This will install NodeJS and NPM. More info here.

这将安装NodeJS和NPM。更多的信息在这里。

Now cd into your working directory and create this file: server.js

现在,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

Next, install required libraries:

接下来,安装所需的库:

npm install socket.io
npm install dnode

You can run this script using node server.js

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

Now we need to edit the clientside javascript. Import Socket.io using this:

现在我们需要编辑clientside javascript。进口套接字。io使用:

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

Then use it like this:

然后像这样使用:

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);
});

You can send data to server like on NodeJS:

您可以像NodeJS一样将数据发送到服务器:

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

Finally, you want to trigger "update" on all connected clients from a PHP script. For this, we need a PHP library for interfacing DNode. You can find it here and its usage is very simple:

最后,您希望在PHP脚本中触发所有连接的客户机上的“更新”。为此,我们需要一个PHP库来与DNode交互。你可以在这里找到它,它的用法非常简单:

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

Calling this PHP script will send title and text to your server.js that will broadcast everything to your connected clients.

调用这个PHP脚本将向服务器发送标题和文本。将所有内容广播到连接的客户端。

Hope this helps!

希望这可以帮助!