PHP向Node / Socket.IO服务器发送消息

时间:2014-02-17 09:53:10

标签: php node.js sockets socket.io

我不太确定我是否会以正确的方式解决这个问题。我想坚持使用我的Socket.IO服务器,并且不想在节点内创建单独的HTTP服务器。有了这个,我可以创建一个PHP客户端,可以直接将数据(例如:玩家从在线商店购买物品)发送到节点Socket.IO服务器吗?

我从这开始:

<?php

class communicator {
   public function connect($address, $port){
      $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

      if($socket){
          try {
              socket_connect($socket, $address, $port);
          } catch(Exception $e){
              throw new Exception($e->getMessage());
          }
      }else{
          throw new Exception('Could not create socket.');
      }
}

?>

套接字似乎可以很好地连接到节点服务器,但是如何直接从PHP客户端开始接收数据呢?

例如:假设我使用socket_write向服务器发送消息。我如何通过Socket.IO获得它?

希望我的问题有道理!

7 个答案:

答案 0 :(得分:4)

即时使用http://elephant.io/进行php和socket.io之间的通信,我只有时间建立连接,3或4秒完成发送数据。

<?php

require( __DIR__ . '/ElephantIO/Client.php');
use ElephantIO\Client as ElephantIOClient;

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

$elephant->init();
$elephant->emit('message', 'foo');
$elephant->close();

答案 1 :(得分:3)

使用最新版本的NSString *searchText = @"{ 124.0, 0.90, 0.556 } { 127.9, 0.9764, 0.456 }"; NSStriong *pattern = @"\\{\\s+([.0-9, ]+)\\s+\\}"; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil]; NSArray *matches = [regex matchesInString:searchText options:0 range:NSMakeRange(0, searchText.length)]; for (NSTextCheckingResult *r in matches) { NSRange numberRange = [r rangeAtIndex:1]; NSLog(@"%@", [searchText substringWithRange:numberRange]); } ,我设法发送了一条消息:

ElephantIO

答案 2 :(得分:3)

我进行了很多搜索,最后找到了一个相对简单的解决方案。

这不需要任何其他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传递数据库更新,而无需数百个客户端查询数据库。

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

该问题已被删除,因为我在几个不同的主题上发布以提高知名度,以帮助人们找到这样的解决方案-希望不要再次删除它。此答案适用于多个问题-谢谢。

答案 3 :(得分:0)

ElephantIO尚未更新到最新的Socket.IO。

因为socket.io v0.9和v1.x非常不同。

Socket.io v1.0:http://socket.io/blog/introducing-socket-io-1-0/

更新:此链接可能有所帮助:https://github.com/psinetron/PHP_SocketIO_Client

答案 4 :(得分:0)

ElephantIO似乎已经死了。我寻找了很多发射器,this one似乎是最快的,而作者似乎很活跃,我建议您进行以下操作

composer require ashiina/socket.io-emitter

然后,在您的php文件上

public function sendMessage($name, $data)
{

    $emitter = new SocketIO\Emitter(array('port' => strval($this->port), 'host' => $this->ipv4));
    $emitter->broadcast->emit($name, $data);
    
}

当然,您需要设置一个$ port和一个$ ipv4,但是该软件包似乎快速且易于使用!您可以使用socket.io服务器端@ user1274820提供的相同代码进行测试

答案 5 :(得分:0)

Socket IO 改变了内部代码,所以 V2 的所有连接都无法连接到 V3,反之亦然。

github 上的所有库都使用 V2 协议,因此如果您使用的是最新的 socketIO V3,那么在这些库上运行会很痛苦。

最简单的解决方案是使用“轮询”和 CURL。

我用symfony做了一个小教程,你可以直接在php上使用CURL,在这个帖子里:

Socket.io 3 and PHP integration

答案 6 :(得分:0)

适用于 socket.io 版本 3 的新答案

https://github.com/socketio/socket.io-protocol#sample-session

工作服务器示例:

直接运行服务器/usr/local/bin/node /socket_io/server/index.js

或通过'forever'运行服务器

/usr/local/bin/forever -a -l /logs/socket.io/forever-log.log -o /logs/socket.io/forever-out.log -e /media/flashmax/var/logs/socket.io/forever-err.log start /socket_io/server/index.js

index.js 文件内容(接收请求):

var io = require('/usr/local/lib/node_modules/socket.io')(8000);
//25-01-2021
// socket.io v3
//iptables -I INPUT 45 -p tcp -m state --state NEW -m tcp --dport 8000 -j ACCEPT
//iptables -nvL --line-number
io.sockets.on('connection', function (socket) {
    socket.on('router', function (channel,newmessage) {
//  console.log('router==========='+channel);
//  console.log('router-----------'+newmessage);
    socket.broadcast.to(channel).emit('new_chat',newmessage);
    });
    socket.on('watch_for_me', function (chanelll) {
        socket.join(chanelll);
//console.log('user watch new '+chanelll);
    });
    socket.on('dont_watch', function (del_chanelll) {
        socket.leave(del_chanelll);
//console.log('user go out' +del_chanelll);
    });
}); 

从 PHP 发送的脚本

<?php
//  php -n /socket_io/test.php
//  dl('curl.so');
//  dl('json.so');

$site_name='http://127.0.0.1:8000/socket.io/?EIO=4&transport=polling&t=mytest';
// create curl resource
$ch = curl_init();

//Request n°1 (open packet)
// set url
curl_setopt($ch, CURLOPT_URL, $site_name);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
$output=substr($output, 1);
$decod=json_decode($output);

//Request n°2 (namespace connection request):
$site_name2=$site_name.'&sid='.$decod->sid;
curl_setopt($ch, CURLOPT_URL, $site_name2);
curl_setopt($ch, CURLOPT_POST, true);
// 4           => Engine.IO "message" packet type
// 0           => Socket.IO "CONNECT" packet type
curl_setopt($ch, CURLOPT_POSTFIELDS, '40');
$output = curl_exec($ch);

// Request n°3 (namespace connection approval)
if ($output==='ok')  {
  curl_setopt($ch, CURLOPT_URL, $site_name2);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $output = curl_exec($ch);
}

// Request n°4 socket.emit('hey', 'Jude') is executed on the server:
if ($output==='ok')  {
curl_setopt($ch, CURLOPT_URL, $site_name2);
curl_setopt($ch, CURLOPT_POST, true);

$message_send='{\\"uuuuu\\": \\"000\\",\\"ryyyd\\":\\"999\\",\\"hyyya\\":\\"<div class=\'fro9\'>llll</div><div class=\'9ig\'>iiiii</div><div class=\'ti9g\'>iiiii</div>\\"}';

curl_setopt($ch, CURLOPT_POSTFIELDS, "42[\"router\",\"chanel@id\",\"$message_send\"]");
$output = curl_exec($ch);
print_r($output);
}

$message_send='send 2 message';
curl_setopt($ch, CURLOPT_POSTFIELDS, "42[\"router\",\"chanel@id\",\"$message_send\"]");
$output = curl_exec($ch);


$message_send='send 3 message';
curl_setopt($ch, CURLOPT_POSTFIELDS, "42[\"router\",\"chanel@id\",\"$message_send\"]");
$output = curl_exec($ch);

// close curl resource to free up system resources
curl_close($ch);  
?>

奖励:设置 apache -> mod_proxy 以访问 socket.io,可用于虚拟主机或整个服务器。

RewriteEngine on
RewriteCond %{QUERY_STRING} transport=polling    [NC]
RewriteRule /(.*)$ http://127.0.0.1:8000/$1 [P,L]
ProxyRequests off
ProxyPass /socket.io/ ws://127.0.0.1:8000/socket.io/
ProxyPassReverse /socket.io/ ws://127.0.0.1:8000/socket.io/