listen
void Worker::listen(void)
Worker ইনস্ট্যান্স সংকেত করার পর এটি নির্বাহ করার জন্য ব্যবহৃত হয়।
এই পদ্ধতি প্রধানত Worker প্রক্রিয়া চালু হওয়ার পর নতুন Worker ইনস্ট্যান্স গতিশীলভাবে তৈরি করতে ব্যবহৃত হয়, যা একই প্রক্রিয়া একাধিক পোর্ট শোনার এবং বিভিন্ন প্রোটোকল সমর্থন করতে সক্ষম। লক্ষ্য করুন যে এই পদ্ধতি শুধু বর্তমান প্রক্রিয়ায় শোনাচ্ছে, নতুন প্রক্রিয়া গতিশীলভাবে তৈরি করবে না, এবং onWorkerStart পদ্ধতিকে কার্যকর করবে না।
যেমন একটি HTTP Worker চালু হওয়ার পর একটি WebSocket Worker ইনস্ট্যান্স তৈরি করা হলে, তখন এই প্রক্রিয়াটি HTTP প্রোটোকল মাধ্যমে প্রবেশ করতে পারবে, আবার WebSocket প্রোটোকল মাধ্যমেও প্রবেশ করতে পারবে। যেহেতু WebSocket Worker এবং HTTP Worker একই প্রক্রিয়ায় রয়েছে, তাই তারা সাধারণ মেমোরি ভ্যারিয়েবল একসাথে অ্যাক্সেস করতে পারে এবং সব সোকের কানেকশন শেয়ার করতে পারে। এটি HTTP অনুরোধ গ্রহণ করার জন্য এবং পরে WebSocket ক্লায়েন্টের সাথে ডেটা প্রেরণ করার উপায় প্রদান করে।
নোট:
যদি PHP সংস্করণ <=7.0 হয়, তবে এটি একাধিক সাবপ্রক্রিয়াতে একই পোর্টের Worker ইনস্ট্যান্স তৈরি করতে সমর্থন করে না। যেমন A প্রক্রিয়াটি 2016 পোর্টের জন্য একটি Worker তৈরি করেছে, তাহলে B প্রক্রিয়া আর 2016 পোর্টের জন্য একটি Worker তৈরি করতে পারবে না, অন্যথায় Address already in use ত্রুটি হবে। যেমন নীচের কোডটি চালানো যাবে না।
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
// ৪টি প্রক্রিয়া
$worker->count = 4;
// প্রতিটি প্রক্রিয়া চালুর পর বর্তমানে একটি নতুন Worker শোনার জন্য তৈরি করবে
$worker->onWorkerStart = function($worker)
{
/**
* ৪টি প্রক্রিয়া চালু হওয়ার সময় 2016 পোর্টের Worker তৈরি হবে
* যখন worker->listen() এ পৌঁছাবে তখন Address already in use ত্রুটি হবে
* যদি worker->count=1 হয় তবে ত্রুটি হবে না
*/
$inner_worker = new Worker('http://0.0.0.0:2016');
$inner_worker->onMessage = 'on_message';
// শোনার জন্য কার্যকর করবে। এখানে Address already in use ত্রুটি হবে
$inner_worker->listen();
};
$worker->onMessage = 'on_message';
function on_message(TcpConnection $connection, $data)
{
$connection->send("hello\n");
}
// Worker চালান
Worker::runAll();
যদি আপনার PHP সংস্করণ >= 7.0 হয়, তাহলে আপনি Worker->reusePort=true সেট করতে পারেন, যাতে একাধিক সাবপ্রক্রিয়া একই পোর্টের Worker তৈরি করতে পারে। নিচের উদাহরণটি দেখুন:
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('text://0.0.0.0:2015');
// ৪টি প্রক্রিয়া
$worker->count = 4;
// প্রতিটি প্রক্রিয়া চালুর পর বর্তমানে একটি নতুন Worker শোনার জন্য তৈরি করবে
$worker->onWorkerStart = function($worker)
{
$inner_worker = new Worker('http://0.0.0.0:2016');
// পোর্ট পুনর্ব্যবহারের জন্য সেট করুন, একই পোর্টের Worker তৈরি করতে পারবেন (PHP >= 7.0 প্রয়োজন)
$inner_worker->reusePort = true;
$inner_worker->onMessage = 'on_message';
// শোনার জন্য কার্যকর করবে। স্বাভাবিকভাবে শোনা হবে
$inner_worker->listen();
};
$worker->onMessage = 'on_message';
function on_message(TcpConnection $connection, $data)
{
$connection->send("hello\n");
}
// Worker চালান
Worker::runAll();
উদাহরণ php ব্যাকএন্ড ক্লায়েন্টকে তাত্ক্ষণিকভাবে বার্তা পাঠানো
নীতিমালা:
-
একটি WebSocket
Workerতৈরি করা, যা ক্লায়েন্ট দীর্ঘ সময়ের জন্য সংযোগ স্থাপন করে বজায় রাখে। -
WebSocket
Workerএর ভিতর একটি textWorkerতৈরি করা। -
WebSocket
Workerএবং textWorkerএকই প্রক্রিয়ায়, যা ক্লায়েন্ট সংযোগ শেয়ার করতে সুবিধাজনক। -
একটি স্বতন্ত্র PHP ব্যাকএন্ড সিস্টেম text প্রোটোকল মারফত
text Workerএর সাথে যোগাযোগ করে। -
text WorkerWebSocket সংযোগ কার্যকর করে ডেটা প্রেরণ করে।
কোড ও পদক্ষেপ
push.php
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// একটি `worker` কনটেইনার ইনিশিয়ালাইজ করুন, 1234 পোর্ট শোনার জন্য
$worker = new Worker('websocket://0.0.0.0:1234');
/*
* নোট: এখানে প্রক্রিয়ার সংখ্যা 1 হওয়া উচিত
*/
$worker->count = 1;
// Worker প্রক্রিয়া চালুর পর একটি text Worker তৈরি করুন, যাতে একটি অভ্যন্তরীণ যোগাযোগ পোর্ট খুলতে পারেন
$worker->onWorkerStart = function($worker)
{
// একটি অভ্যন্তরীণ পোর্ট চালু করুন, যাতে অভ্যন্তরীণ সিস্টেম ডেটা প্রেরণ করতে পারে, Text প্রোটোকল ফরম্যাট পাঠ্য+লাইনে পরিবর্তন
$inner_text_worker = new Worker('text://0.0.0.0:5678');
$inner_text_worker->onMessage = function(TcpConnection $connection, $buffer)
{
// $data অ্যারে ফরম্যাট, যার মধ্যে uid আছে, যা সেই uid এর পৃষ্ঠায় ডেটা প্রেরণ করে
$data = json_decode($buffer, true);
$uid = $data['uid'];
// Workerman দিয়ে uid এর পৃষ্ঠায় ডেটা প্রেরণ করুন
$ret = sendMessageByUid($uid, $buffer);
// প্রেরণের ফলাফল ফেরৎ দিন
$connection->send($ret ? 'ok' : 'fail');
};
// ## শোনা कार्यকরন ##
$inner_text_worker->listen();
};
// uid থেকে connection ম্যাপিং সংরক্ষণ করার জন্য একটি নতুন প্রপার্টি যোগ করুন
$worker->uidConnections = array();
// যখন একটি ক্লায়েন্ট বার্তা পাঠায়, তখন কার্যকর হওয়ার জন্য কলব্যাক ফাংশন
$worker->onMessage = function(TcpConnection $connection, $data)
{
global $worker;
// বর্তমান ক্লায়েন্টটি কি ইতিমধ্যেই যাচাইকৃত কিনা যাচাই করুন, অর্থাৎ, uid কি সেট করা হয়েছে
if(!isset($connection->uid))
{
// যদি যাচাইকৃত না হয় তবে প্রথম প্যাকেজকে uid হিসাবে বিবেচনা করুন (প্রদর্শনের সুবিধার জন্য, প্রকৃত যাচাইকরণ হয়নি)
$connection->uid = $data;
/* uid থেকে connection ম্যাপিং সংরক্ষণ করুন, যাতে uid মারফত connection সহজে খুঁজে পাওয়া যায়,
* নির্দিষ্ট uid এর জন্য ডেটা প্রেরণের ব্যবস্থা প্রস্তুত করতে
*/
$worker->uidConnections[$connection->uid] = $connection;
return;
}
};
// যখন একটি ক্লায়েন্ট সংযোগ বিচ্ছিন্ন হয়
$worker->onClose = function(TcpConnection $connection)
{
global $worker;
if(isset($connection->uid))
{
// সংযোগ বিচ্ছিন্ন হলে ম্যাপিংটি মুছে ফেলুন
unset($worker->uidConnections[$connection->uid]);
}
};
// সমস্ত যাচাইকৃত ব্যবহারকারীদের জন্য ডেটা প্রেরণ
function broadcast($message)
{
global $worker;
foreach($worker->uidConnections as $connection)
{
$connection->send($message);
}
}
// uid এর জন্য ডেটা প্রেরণ
function sendMessageByUid($uid, $message)
{
global $worker;
if(isset($worker->uidConnections[$uid]))
{
$connection = $worker->uidConnections[$uid];
$connection->send($message);
return true;
}
return false;
}
// সমস্ত worker চালান
Worker::runAll();
ব্যাকএন্ড সেবা চালু করুন
php push.php start -d
ফ্রন্টএন্ড প্রাপ্তির js কোড
var ws = new WebSocket('ws://127.0.0.1:1234');
ws.onopen = function(){
var uid = 'uid1';
ws.send(uid);
};
ws.onmessage = function(e){
alert(e.data);
};
ব্যাকএন্ড বার্তা প্রেরণের কোড
// অভ্যন্তরীণ প্রেরণ পোর্টে socket সংযোগ তৈরি করুন
$client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1);
// প্রেরণের ডেটা, uid ক্ষেত্র সহ, যা এই(uid) uid এ প্রেরণ করে
$data = array('uid'=>'uid1', 'percent'=>'88%');
// ডেটা প্রেরণ করুন, লক্ষ্য করুন 5678 পোর্ট Text প্রোটোকল পোর্ট, Text প্রোটোকল ডেটার শেষের দিকে লাইনে পরিবর্তন সংযোগ করতে হয়
fwrite($client, json_encode($data)."\n");
// প্রেরণের ফলাফল পড়ুন
echo fread($client, 8192);