Websockets PHP / AJAX / Javascript刷新客户端

时间:2014-05-03 17:05:43

标签: javascript php jquery ajax

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

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

以下内容可以帮助您理解:

enter image description here

  1. 客户端连接到网页。
  2. SQL select在我的数据库上执行
  3. 结果已收到并显示在网页上。
  4. 客户端已连接(通过websockets)并查看数据库中的信息。
  5. 我。如果我在数据库中插入信息,我发送一个POST请求(不是来自HTML表单,没有提交,只是一个POST请求,就像我使用Postman来测试web服务一样)。发送请求时,通过调用Javascript函数刷新客户端...
  6. 以下是我所做的:

    • 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 select请求的地方(工作正常)

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

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

    任何帮助都很贴切。提前谢谢。

    此致 Lapinou。

1 个答案:

答案 0 :(得分:8)

我已经从您提供的链接中看到server.php,只是:

  1. 接受传入连接
  2. 循环浏览所有已连接的套接字
  3. 如果这些套接字中的任何一个有数据,它会回复每个其他客户端。
  4. 您需要更改此循环并为邮件添加其他来源,并且您有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上的版本很旧,所以我们从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脚本触发所有连接的客户端上的“更新”。为此,我们需要一个PHP库来连接DNode。你可以找到它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,它将向连接的客户端广播所有内容。

    希望这有帮助!