Websockets PHP/AJAX/Javascript刷新客户端

Lap*_*nou 7 javascript php ajax jquery

我正在使用带有PHP和一些Javascript的websockets.我将数据库中的一些信息显示给我的客户端.我的目标是在信息插入我的数据库时刷新客户端.要在我的数据库中插入一些数据,我从我的PC发送一个帖子请求.

此刻,我可以刷新客户端每10秒调用一次函数.但是,只有在该页面上发送POST请求时,我才想刷新.

这可以帮助您理解:

在此输入图像描述

  1. 客户端连接到网页.
  2. SQL select在我的数据库上执行
  3. 结果将被接收并显示在网页上.
  4. 客户端已连接(通过websockets)并查看数据库中的信息.
  5. 我.如果我在数据库中插入信息,我发送一个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));
            }
        );
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • infos.php:我在哪里执行SQL select请求(工作正常)

  • server.php:服务器端的代码在哪里.(工作良好)

好.我真的不知道怎么能实现这个目标.如何通知并调用displayInfo(r)函数; 如果POST请求发送到此页面.

任何帮助都很贴切.先感谢您.

此致,Lapinou.

Joh*_*ler 8

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

  1. 接受传入的连接
  2. 循环通过所有连接的套接字
  3. 如果这些套接字中的任何一个具有数据,则它会回复每个其他客户端.

您需要更改此循环并为消息添加其他来源,并且您有2个选项.您可以池化数据库或打开另一个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的版本很旧,所以我们从这里添加一个PPA :

sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install node
Run Code Online (Sandbox Code Playgroud)

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

现在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
Run Code Online (Sandbox Code Playgroud)

接下来,安装所需的库:

npm install socket.io
npm install dnode
Run Code Online (Sandbox Code Playgroud)

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

现在我们需要编辑客户端javascript.使用以下方法导入Socket.io:

<script type="text/javascript" src="http://YOURHOSTNAME:SOCKETIOPORT/socket.io/socket.io.js"></script>
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

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);
});
Run Code Online (Sandbox Code Playgroud)

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

socket.emit('message', {foo: 'bar'});
Run Code Online (Sandbox Code Playgroud)

最后,您希望从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"
)));
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助!