草庐IT

javascript - Websockets PHP/AJAX/Javascript 刷新客户端

coder 2024-01-03 原文

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

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

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

  1. 客户端正在连接到网页。
  2. 在我的数据库上执行 SQL 选择
  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));
            }
        );
    }
    
  • infos.php:我在其中执行 SQL 选择请求(工作正常)

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

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

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

问候, 拉皮努。

最佳答案

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

  1. 接受传入连接
  2. 遍历所有连接的套接字
  3. 如果这些套接字中的任何一个有数据,它就会回复所有其他客户端。

你需要改变这个循环并添加另一个消息源,你有两个选择。您可以汇集一个数据库或打开另一个 TCP 套接字并从那里读取。

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


编辑:这是我的做法。

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

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

首先我们安装 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,它将向您连接的客户端广播所有内容。

希望这对您有所帮助!

关于javascript - Websockets PHP/AJAX/Javascript 刷新客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23447413/

有关javascript - Websockets PHP/AJAX/Javascript 刷新客户端的更多相关文章

  1. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  2. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  3. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  4. ruby - 在 TCPServer (Ruby) 中,我如何从客户端获取 IP/MAC? - 2

    我想在Ruby的TCPServer中获取客户端的IP地址。以及(如果可能的话)MAC地址。例如,Ruby中的时间服务器,请参阅评论。tcpserver=TCPServer.new("",80)iftcpserverputs"Listening"loopdosocket=tcpserver.acceptifsocketThread.newdoputs"Connectedfrom"+#HERE!HowcanigettheIPAddressfromtheclient?socket.write(Time.now.to_s)socket.closeendendendend非常感谢!

  5. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  6. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

  7. ruby-on-rails - 为什么我必须在使用客户验证器后重新加载 rspec 中的记录? - 2

    我有一个模型User,它在创建后的回调中创建了选项#Userhas_one:user_optionsafter_create:create_optionsprivatedefcreate_optionsUserOptions.create(user:self)end我对此有一些简单的Rspec覆盖:describe"newuser"doit"createsuser_optionsaftertheuseriscreated"douser=create(:user)user.user_options.shouldbe_kind_of(UserOptions)endend一切正常,直到我将自

  8. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

    我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

  9. ruby - 如何获得带有 SSL 客户端证书的 HTTPS 请求以与 Ruby EventMachine 一起使用? - 2

    我正在尝试使用RubyEventMachine访问使用SSL证书身份验证的HTTPSWeb服务,但我没有让它工作。我编写了以下简单代码块来对其进行端到端测试:require'rubygems'require'em-http'EventMachine.rundourl='https://foobar.com/'ssl_opts={:private_key_file=>'/tmp/private.key',:cert_chain_file=>'/tmp/ca.pem',:verify_peer=>false}http=EventMachine::HttpRequest.new(url).g

  10. ruby-on-rails - 在 Ruby on Rails 应用程序中使用客户端 SSL - 2

    我正在为需要与API建立SSL连接的客户端开发应用程序。我得到了三个文件;一个信任根证书(.cer)文件、一个中间证书(.cer)文件和一个签名的响应文件。我得到的安装说明与IIS或Javakeytool程序有关;我正在用RubyonRails构建应用程序,所以这两种方法都不是一个选项(据我所知)。证书由运行API服务的组织自签名,看来我获得了客户端证书以相互验证https连接。我不确定如何使用我的应用程序中的证书连接和使用API签名响应文件的作用我读过"Usingaself-signedcertificate"和thisarticleonOpenSSLinRuby但两者似乎都不是很到

随机推荐