[英]Creating Node.js + socket.io Server/Client with users authentication, sending/receiving data
[英]PHP sending message to Node / Socket.IO server
我不太确定我是否以正确的方式解决这个问题。 我想坚持使用我的 Socket.IO 服务器,并且不想在节点内创建单独的 HTTP 服务器。 有了这个,我可以创建一个可以将数据(例如:玩家从网上商店购买物品)直接发送到节点 Socket.IO 服务器的 PHP 客户端吗?
我从这个开始:
<?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 获得它?
希望我的问题有意义!
我搜索了很多,最后找到了一个相对简单的解决方案。
这不需要任何额外的 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 传递数据库更新,而无需数百个客户端查询数据库。
我希望我能早点找到这个 - 希望这会有所帮助! 😉
后期编辑:不确定这是否是一个要求,但我将其添加到我的 http.conf(Apache 配置)中:
我想我会把代码放在这里,以防它对任何人有帮助。
在 httpd.conf 中,我添加了以下代码:
RewriteEngine On
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule .* ws://localhost:8080%{REQUEST_URI} [P]
ProxyRequests Off
ProxyPass /socket.io http://localhost:8080/socket.io retry=0
ProxyPassReverse /socket.io http://localhost:8080/socket.io retry=0
ProxyPass "/node" "http://localhost:8080/"
我使用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();
使用最新版本的ElephantIO
,我设法发送了一条消息:
include_once("vendor/autoload.php");
use ElephantIO\Exception\ServerConnectionFailureException;
$client = new \ElephantIO\Client(new \ElephantIO\Engine\SocketIO\Version1X('http://localhost:9000'));
try
{
$client->initialize();
$client->emit('message', ['title' => 'test']);
$client->close();
}
catch (ServerConnectionFailureException $e)
{
echo 'Server Connection Failure!!';
}
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
ElephantIO 似乎已经死了。 我找了很多发射器,这个似乎是最快的,而且作者似乎很活跃,我建议这样做
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 提供的相同代码来测试它
Socket IO 改变了内部代码,因此所有从 V2 开始的连接都无法连接到 V3,反之亦然。
github 上的所有库都使用 V2 协议,因此如果您使用的是最新的 socketIO V3,那么在这些库上运行会很痛苦。
最简单的解决方案是使用“轮询”和 CURL。
我用 symfony 做了一个迷你教程,你可以直接在 php 上使用 CURL,在这篇文章中:
https://github.com/socketio/socket.io-protocol#sample-session
工作服务器示例:
直接运行服务器/usr/local/bin/node /socket_io/server/index.js
或通过“永远”运行服务器
/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/
我只能从 xampp\\mysql\\data 中删除这个文件“multi-master.info”,然后我的问题就会解决,我可以重新启动 xampp,它会创建一个新文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.