在Socket.io中使用PHP


128

是否可以在客户端使用Sockets.io并与服务器上基于PHP的应用程序进行通信?PHP甚至支持这种“长寿命连接”代码编写方式吗?

我为socket.io找到的所有示例代码似乎都是针对服务器端的node.js,因此没有帮助。


3
可能重复:来自php源的
Socket.io

您可能只考虑推动器。它有一个漂亮的PHP库供我使用。
Devin G Rhode

Answers:


98

要回答这个问题可能为时已晚,但这就是我的发现。

我不想争论节点是否比php更好的事实,这不是重点。

解决的办法是:我还没有找到用于PHP的socket.io的任何实现。

但是有一些方法可以实现WebSockets。有一个jQuery插件可让您使用Websockets,同时为不支持的浏览器优雅降级。在PHP方面,该类似乎是PHP WS服务器使用最广泛的


1
如果您想要php websocket服务器实现,则phpwebsocket类确实是可行的方法。但是,这与问题无关。OP已经实现了WS服务器(socket.io),并要求与php应用程序进行通信的方法。
kasper Taeymans

72

如果您想将socket.io与php一起使用,这可能是您的答案!

项目网站:

大象

它们也在github上:

https://github.com/wisembly/elephant.io

Elephant.io提供了完全用PHP编写的socket.io客户端,该客户端应可在项目中的任何地方使用。

它是一个轻巧易用的库,旨在通过socket.io和websockets为PHP应用程序带来一些实时功能,以完成无法使用完整javascript进行的操作。

项目网站上的示例(通过php与websocket服务器通信)

PHP服务器

use ElephantIO\Client as Elephant;

$elephant = new Elephant('http://localhost:8000', 'socket.io', 1, false, true, true);

$elephant->init();
$elephant->send(
    ElephantIOClient::TYPE_EVENT,
    null,
    null,
    json_encode(array('name' => 'foo', 'args' => 'bar'))
);
$elephant->close();

echo 'tryin to send `bar` to the event `foo`';

套接字io服务器

var io = require('socket.io').listen(8000);

io.sockets.on('connection', function (socket) {
  console.log('user connected!');

  socket.on('foo', function (data) {
    console.log('here we are in action event and data is: ' + data);
  });
});

2
我会在这里给您+1,但看起来这仍然无法在生产环境中使用。
海滨别墅

17
我已经看过这个了,但是有一件事使我感到困惑。让PHP实现sockets.io服务器不是这里的重点吗?相反,Elepant.io似乎是sockets.io客户端的PHP实现,您可以将其连接到其他sockets.io服务器(这意味着Elephant.io不会监听来自sockets.io客户端的连接,给他们并提供服务)?
皮条客Trizkit

正是我要寻找的东西,可惜持久的连接处于开发的早期阶段。
slezadav

8
大家好。Elephant.io的目的只是将事件从PHP触发到socket.io服务器。不要打开持久的连接。但是能够快速连接并发送事件/消息。我们在生产中使用它,它就像一个魅力。
guillaumepotier 2013年

3
该图书馆不再维护,对我们而言有一些问题
Flion


14

如果您真的想将PHP用作socket.io的后端,那么这里就是我所发现的。两种socket.io替代php服务器端。

https://github.com/walkor/phpsocket.io

https://github.com/RickySu/phpsocket.io

这样,第一个存储库的示例代码。

use PHPSocketIO\SocketIO;

// listen port 2021 for socket.io client
$io = new SocketIO(2021);
$io->on('connection', function($socket)use($io){
  $socket->on('chat message', function($msg)use($io){
    $io->emit('chat message', $msg);
  });
});

7

对于您提到的“长期连接”,可以使用Ratchet for PHP。这是一个基于Stream Socket函数构建的库,自PHP 5以来,该函数就已支持PHP。

对于客户端,您需要使用HTML5支持的WebSocket而不是Socket.io(因为您知道,socket.io仅适用于node.js)。

如果仍要使用Socket.io,可以尝试以下方法:-查找并获取供客户端使用的socket.io.js-与Ratchet一起模拟socket.io在服务器上的工作方式

希望这可以帮助!


6

Erm,为什么要呢?将PHP留在后端和NodeJS / Sockets上以执行其非阻塞性操作。

以下是一些入门指南:http : //groups.google.com/group/socket_io/browse_thread/thread/74a76896d2b72ccc

就个人而言,我有一个运行在端点的运行程序,该端点正在明确侦听来自PHP的交互。

例如,如果我已向用户发送电子邮件,则希望socket.io向用户显示实时通知。

想要从socket.io到php进行交互,那么您可以执行以下操作:

var http = require('http'),
            host = WWW_HOST,
            clen = 'userid=' + userid,
            site = http.createClient(80, host),
            request = site.request("POST", "/modules/nodeim/includes/signonuser.inc.php",  
                {'host':host,'Content-Length':clen.length,'Content-Type':'application/x-www-form-urlencoded'});                     

request.write('userid=' + userid);      
request.end();  

认真地说,PHP非常适合做服务器端的事情,并且使其与它现在在该域中没有地位的连接保持一致。当您有websocket或flashsocket时,为什么要进行长轮询。


32
因为我们中有些人只能得到便宜的主机,所以只能使用php和mysql。
兰博

31
因为我们中有些人必须使用依赖PHP的现有框架。例如,我们开发和销售一个PHP脚本,但是希望通过使用websockets来改善IM,我们不想编写所有已经实现socket.io的后备,但是我们不能要求客户端提供NodeJS。
Purefan

3
@PaulM:我尝试了几个<$ 10的VPS提供商,而所有这些真的很烂。每一个都非常缓慢,发生故障时,支持会很糟糕等。另一方面,在芬兰,通过adsl订阅获得质量不错的虚拟主机(但仅包含php / mysql / static文件)并不罕见,而无需支付任何额外费用。所以不,能够以5美元的价格购买糟糕的VPS绝对不是解决方案。
Olli 2012年

4
对于价格低于10美元的VPS提供商,到目前为止,我发现的唯一一个不错的提供商是digitalocean.com。但是那个很好。
Aeolun

3
我不同意 我认为这样的答案非常重要。有人告诉您“您使用的是错误的”可能比帮助您错误使用的人更有价值。
里克2013年

6

我知道奋斗的人!但是我最近几乎与Workerman一起工​​作。如果您还没有偶然发现过这个php框架,那么最好检查一下!

好吧,Workerman是一个异步事件驱动的PHP框架,可轻松构建快速,可扩展的网络应用程序。(我只是从他们的网站hahahah http://www.workerman.net/en/复制并粘贴了该内容)

解释此问题的简单方法是,当进行Web套接字编程时,您真正需要做的就是在服务器或本地服务器(无论您在哪里工作)中拥有2个文件。

  1. server.php(将响应所有客户端请求的源代码)

  2. client.php / client.html(将执行请求内容的源代码)

因此,基本上,您首先在server.php上对代码进行修改,然后启动服务器。通常,当我使用Windows时,会增加更多的麻烦,因此我通过以下命令运行服务器-> php server.php start

好吧,如果您使用的是xampp。这是一种方法。转到要放置文件的位置。在我们的例子中,我们将把文件放入

C:/xampp/htdocs/websocket/server.php

C:/xampp/htdocs/websocket/client.php或client.html

假设您已经在本地服务器中拥有这些文件。打开您的Git Bash或命令行或终端,或者使用的任何一个,然后在此处下载php库。

https://github.com/walkor/Workerman

https://github.com/walkor/phpsocket.io

我通常通过composer下载它,然后将这些文件自动加载到我的php脚本中。

并检查此一项。这真的很重要!您需要此javascript库,以便client.php或client.html 在运行时与server.php通信。

https://github.com/walkor/phpsocket.io/tree/master/examples/chat/public/socket.io-client

我只是将socket.io-client文件夹复制并粘贴到与server.php和client.php相同的级别上

这是server.php源代码

<?php
require __DIR__ . '/vendor/autoload.php';

use Workerman\Worker;
use PHPSocketIO\SocketIO;

// listen port 2021 for socket.io client
$io = new SocketIO(2021);
$io->on('connection', function($socket)use($io){
    $socket->on('send message', function($msg)use($io){
        $io->emit('new message', $msg);
    });
});

Worker::runAll();

这是client.phpclient.html源代码

<!DOCTYPE html>
<html>
    <head>
        <title>Chat</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">        
    </head>
    <body>
        <div id="chat-messages" style="overflow-y: scroll; height: 100px; "></div>        
        <input type="text" class="message">
    </body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>    
    <script src="socket.io-client/socket.io.js"></script>  
    <script>
            var socket = io.connect("ws://127.0.0.1:2021");

            $('.message').on('change', function(){
                socket.emit('send message', $(this).val());
                $(this).val('');
            });

            socket.on('new message', function(data){
                $('#chat-messages').append('<p>' + data +'</p>');
            });
    </script>
</html>

再次打开命令行或git bash或将server.php文件放入其中的终端。因此,在我们的例子中,这是C:/ xampp / htdocs / websocket /并输入php server.php启动并按Enter。

然后转到浏览器并键入http://localhost/websocket/client.php来访问您的站点。然后,在该文本框中键入任何内容,您将在旅途中看到基本的php websocket!

您只需要记住。在Web套接字编程中,它只需要一个服务器和一个客户端。首先运行服务器代码,然后打开客户端代码。在那里,您拥有了!希望这可以帮助!



3

这个怎么样 ?PHPSocketio ?? 它是socket.io php服务器端的替代方案。事件循环基于pecl事件扩展。直到现在我还没有尝试过。


3

我们现在到了2018年,很高兴,有一种方法可以在php上实现WS和WAMPServer。叫做棘轮


2

我还没有尝试过,但是您应该可以使用ReactPHP和这个socket组件来做到这一点。看起来就像Node,但是在PHP中。



0

我一直在寻找一种非常简单的方法来使PHP向客户端发送socket.io消息。

这不需要任何其他PHP库-它仅使用套接字。

与其尝试像许多其他解决方案一样尝试连接到websocket界面,不如连接到node.js服务器并用于.on('data')接收消息。

然后,socket.io可以将其转发给客户端。

像这样在Node.js中检测来自PHP服务器的连接:

//You might have something like this - just included to show object setup
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

server.on("connection", function(s) {
    //If connection is from our server (localhost)
    if(s.remoteAddress == "::ffff:127.0.0.1") {
        s.on('data', function(buf) {
            var js = JSON.parse(buf);
            io.emit(js.msg,js.data); //Send the msg to socket.io clients
        });
    }
});

这是令人难以置信的简单php代码-我将其包装在一个函数中-您可能会想出更好的东西。

请注意,这8080是我的Node.js服务器的端口-您可能需要更改。

function sio_message($message, $data) {
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    $result = socket_connect($socket, '127.0.0.1', 8080);
    if(!$result) {
        die('cannot connect '.socket_strerror(socket_last_error()).PHP_EOL);
    }
    $bytes = socket_write($socket, json_encode(Array("msg" => $message, "data" => $data)));
    socket_close($socket);
}

您可以像这样使用它:

sio_message("chat message","Hello from PHP!");

您还可以发送转换为json并传递给客户端的数组。

sio_message("DataUpdate",Array("Data1" => "something", "Data2" => "something else"));

这是一种“信任”客户端从服务器获取合法消息的有用方法。

您还可以让PHP传递数据库更新,而无需让数百个客户端查询数据库。

我希望能早点找到它-希望这会有所帮助!😉


1
好主意,我正在寻找一种跳过redis的方法(如果那是个好主意)!第一个代码中有一个错字,在之后的是一个分号s.remoteAddress;。但是,我没有使其正常工作。我在节点中得到连接,它检测到连接,remoteaddress是正确的,但是s.on('data')从不发生,但是什么也没有发生。我也尝试s.on('msg')过 我正在使用您的确切PHP代码。我在节点服务器上使用https,但这没关系吗?
尼古拉斯

@Niclas嘿,对错字感到抱歉-简直不敢相信。您的节点服务器是否在端口上运行8080?如果不是,则需要更改端口。如果是这样,请检查Remote Address返回的内容-确保它是回送/本地地址-它可能与您的服务器设置不同。为了进行测试,您可以删除以下行if(s.remoteAddress == "::ffff:127.0.0.1")
user1274820

感谢您的快速答复!我一路成功完成了console.log,即使remoteaddress正确,它也没有进入s.on('data')部分。有没有办法测试发送了什么消息?请重新阅读我的评论,看看我是否错过了什么。我可能将其作为发布代码的新问题开始,但这几乎与您的完全一样。
尼古拉斯'18

我将其作为一个新问题开始,以使其更易于详细讨论:stackoverflow.com/questions/53689391/…–
Niclas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.