কিছু উদাহরণ

উদাহরণ ১

প্রোটোকল সং 정의

  • প্রধান অংশ ১০ টি বাইট দীর্ঘ যা সম্পূর্ণ ডেটা প্যাকেজের দৈর্ঘ্য সংরক্ষণ করতে ব্যবহার করা হয়, যদি সংখ্যা কম হয় তবে ০ পূরণ করুন
  • ডেটা ফরম্যাট হলো xml

ডেটা প্যাকেজের নমুনা

0000000121<?xml version="1.0" encoding="ISO-8859-1"?>
<request>
    <module>user</module>
    <action>getInfo</action>
</request>

এখানে 0000000121 সম্পূর্ণ ডেটা প্যাকেজের দৈর্ঘ্য নির্দেশ করে, তারপর xml ডেটা ফরম্যাটের প্যাকেজের বিষয়বস্তু আসছে

প্রোটোকল বাস্তবায়ন

namespace Protocols;
class XmlProtocol
{
    public static function input($recv_buffer)
    {
        if(strlen($recv_buffer) < 10)
        {
            // ১০ বাইটের জন্য যথেষ্ট নয়, ০ ফেরত দিন এবং ডেটার জন্য অপেক্ষা করুন
            return 0;
        }
        // প্যাকেজের দৈর্ঘ্য ফিরিয়ে দেয়, যা প্রধান তথ্যের দৈর্ঘ্য + প্যাকেজের বিষয়বস্তু
        $total_len = base_convert(substr($recv_buffer, 0, 10), 10, 10);
        return $total_len;
    }

    public static function decode($recv_buffer)
    {
        // অনুরোধ প্যাকেজের বিষয়বস্তু
        $body = substr($recv_buffer, 10);
        return simplexml_load_string($body);
    }

    public static function encode($xml_string)
    {
        // প্যাকেজের বিষয়বস্তু + প্রধান অংশের দৈর্ঘ্য
        $total_length = strlen($xml_string)+10;
        // দৈর্ঘ্য অংশ ১০ বাইট পূর্ণ করুন, সংখ্যা কম হলে ০ পূরণ করুন
        $total_length_str = str_pad($total_length, 10, '0', STR_PAD_LEFT);
        // ডেটা ফেরত দিন
        return $total_length_str . $xml_string;
    }
}

উদাহরণ ২

প্রোটোকল সং définition

  • প্রধান অংশ ৪ বাইট নেটওয়ার্ক বাইট অর্ডার unsigned int, সর্বমোট প্যাকের দৈর্ঘ্য নির্দেশ করে
  • ডেটার অংশ হলো Json স্ট্রিং

ডেটা প্যাকেজের নমুনা

****{"type":"message","content":"hello all"}

এখানে প্রধান অংশের চারটি বাইট * প্রতীক নেটওয়ার্ক বাইট অর্ডারে unsigned int ডেটা নির্দেশ করে, যা অদৃশ্য অক্ষর, তারপর Json ডেটা ফরম্যাটের প্যাকেজের বিষয়বস্তু আসছে

প্রোটোকল বাস্তবায়ন

namespace Protocols;
class JsonInt
{
    public static function input($recv_buffer)
    {
        // প্রাপ্ত ডেটা ৪ বাইটের জন্য যথেষ্ট নয়, প্যাকেজের দৈর্ঘ্য জানানো সম্ভব নয়, ০ ফেরত দিন এবং ডেটার জন্য অপেক্ষা করুন
        if(strlen($recv_buffer)<4)
        {
            return 0;
        }
        // unpack ফাংশন ব্যবহার করে প্রধান অংশের ৪ বাইটকে সংখ্যায় রূপান্তর করুন, প্রধান অংশের ৪ বাইট পুরো ডেটা প্যাকেজের দৈর্ঘ্য
        $unpack_data = unpack('Ntotal_length', $recv_buffer);
        return $unpack_data['total_length'];
    }

    public static function decode($recv_buffer)
    {
        // প্রধান ৪ বাইট বাদ দিয়ে প্যাকেজের Json ডেটা পান
        $body_json_str = substr($recv_buffer, 4);
        // json ডিকোড করুন
        return json_decode($body_json_str, true);
    }

    public static function encode($data)
    {
        // Json কোডিং করে প্যাকেজের বিষয়বস্তু পান
        $body_json_str = json_encode($data);
        // পুরো প্যাকেজের দৈর্ঘ্য নির্ণয় করুন, প্রধান ৪ বাইট + প্যাকেজের বিষয়বস্তু বাইট সংখ্যা
        $total_length = 4 + strlen($body_json_str);
        // প্যাকেজের ডেটা ফেরত দিন
        return pack('N',$total_length) . $body_json_str;
    }
}

উদাহরণ ৩ (বাইনरी প্রোটোকল ব্যবহার করে ফাইল আপলোড)

প্রোটোকল সং সংজ্ঞা

struct
{
  unsigned int total_len;  // পুরো প্যাকেজের দৈর্ঘ্য, বিগ-এন্ড নেটওয়ার্ক বাইট অর্ডার
  char         name_len;   // ফাইল নামের দৈর্ঘ্য
  char         name[name_len]; // ফাইল নাম
  char         file[total_len - BinaryTransfer::PACKAGE_HEAD_LEN - name_len]; // ফাইলের ডেটা
}

প্রোটোকল নমুনা

 *****logo.png****************** 

এখানে প্রধান অংশের চারটি বাইট প্রতীক নেটওয়ার্ক বাইট অর্ডারে একটি unsigned int ডেটা নির্দেশ করে, যা অদৃশ্য অক্ষর, পঞ্চম একটি বাইটে ফাইল নামের দৈর্ঘ্য সংরক্ষণ করে, তারপর ফাইল নাম এবং তারপর মৌলিক বাইনরি ফাইল ডেটা আসে

প্রোটোকল বাস্তবায়ন

namespace Protocols;
class BinaryTransfer
{
    // প্রোটোকল প্রধান অংশের দৈর্ঘ্য
    const PACKAGE_HEAD_LEN = 5;

    public static function input($recv_buffer)
    {
        // যদি প্রধান অংশের দৈর্ঘ্য যথেষ্ট না হয় তবে অপেক্ষা করুন
        if(strlen($recv_buffer) < self::PACKAGE_HEAD_LEN)
        {
            return 0;
        }
        // আনপ্যাক করুন
        $package_data = unpack('Ntotal_len/Cname_len', $recv_buffer);
        // প্যাকেজের দৈর্ঘ্য ফেরত দিন
        return $package_data['total_len'];
    }

    public static function decode($recv_buffer)
    {
        // আনপ্যাক করুন
        $package_data = unpack('Ntotal_len/Cname_len', $recv_buffer);
        // ফাইল নামের দৈর্ঘ্য
        $name_len = $package_data['name_len'];
        // ডেটা স্ট্রীম থেকে ফাইল নাম বের করুন
        $file_name = substr($recv_buffer, self::PACKAGE_HEAD_LEN, $name_len);
        // ডেটা স্ট্রীম থেকে ফাইল মৌলিক তথ্য বের করুন
        $file_data = substr($recv_buffer, self::PACKAGE_HEAD_LEN + $name_len);
         return array(
             'file_name' => $file_name,
             'file_data' => $file_data,
         );
    }

    public static function encode($data)
    {
        // আপনি প্রয়োজন অনুযায়ী ক্লায়েন্টকে প্রেরিত তথ্য কোড করতে পারেন, এখানে কেবল টেক্সট হিসাবে ফিরিয়ে দেয়া হয়েছে
        return $data;
    }
}

সার্ভার প্রোটোকল ব্যবহার উদাহরণ

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('BinaryTransfer://0.0.0.0:8333');
// tmp-তে ফাইল সংরক্ষণ করুন
$worker->onMessage = function(TcpConnection $connection, $data)
{
    $save_path = '/tmp/'.$data['file_name'];
    file_put_contents($save_path, $data['file_data']);
    $connection->send("upload success. save path $save_path");
};

Worker::runAll();

ক্লায়েন্ট ফাইল client.php (এখানে php ব্যবহার করে ক্লায়েন্ট আপলোডের নকল করা)

<?php
/** ফাইল আপলোড ক্লায়েন্ট **/
// আপলোড ঠিকানা
$address = "127.0.0.1:8333";
// আপলোড ফাইলের পথ প্যারামিটার পরীক্ষা করুন
if(!isset($argv[1]))
{
   exit("use php client.php \$file_path\n");
}
// আপলোড ফাইলের পথ
$file_to_transfer = trim($argv[1]);
// আপলোডের ফাইল স্থানীয়ভাবে অস্তিত্বহীন 
if(!is_file($file_to_transfer))
{
    exit("$file_to_transfer not exist\n");
}
// সোকার সংযোগ তৈরি করুন
$client = stream_socket_client($address, $errno, $errmsg);
if(!$client)
{
    exit("$errmsg\n");
}
// ব্লকিং মোডে সেট করুন
stream_set_blocking($client, 1);
// ফাইল নাম
$file_name = basename($file_to_transfer);
// ফাইল নামের দৈর্ঘ্য
$name_len = strlen($file_name);
// ফাইল মৌলিক ডেটা
$file_data = file_get_contents($file_to_transfer);
// প্রধান অংশের দৈর্ঘ্য ৪ বাইট প্যাকেজের দৈর্ঘ্য + ১ বাইটের ফাইল নামের দৈর্ঘ্য 
$PACKAGE_HEAD_LEN = 5;
// প্রোটোকল প্যাকেজ
$package = pack('NC', $PACKAGE_HEAD_LEN  + strlen($file_name) + strlen($file_data), $name_len) . $file_name . $file_data;
// আপলোড সম্পন্ন করুন
fwrite($client, $package);
// ফলাফল মুদ্রণ করুন
echo fread($client, 8192),"\n";

ক্লায়েন্ট ব্যবহার উদাহরণ

কমান্ড লাইনে চালান php client.php <ফাইলের পথ>

যথা php client.php abc.jpg

উদাহরণ ৪ (টেক্সট প্রোটোকল ব্যবহার করে ফাইল আপলোড)

প্রোটোকল সং সংজ্ঞা

json+newline, json মধ্যে ফাইলের নাম এবং base64_encode কোডিত (১/৩ বেশি আকার তৈরি করবে) ফাইল ডেটা অন্তর্ভুক্ত

প্রোটোকল নমুনা

{"file_name":"logo.png","file_data":"PD9waHAKLyo......"}\n

শেষাংশে একটি নতুন লাইন রয়েছে, PHP-তে এটি ডাবল কোটেশন চিহ্ন "\n" দ্বারা চিহ্নিত করা হয়

প্রোটোকল বাস্তবায়ন

namespace Protocols;
class TextTransfer
{
    public static function input($recv_buffer)
    {
        $recv_len = strlen($recv_buffer);
        if($recv_buffer[$recv_len-1] !== "\n")
        {
            return 0;
        }
        return strlen($recv_buffer);
    }

    public static function decode($recv_buffer)
    {
        // প্যাকেজ আনপ্যাক করুন
        $package_data = json_decode(trim($recv_buffer), true);
        // ফাইল নাম নিন
        $file_name = $package_data['file_name'];
        // base64_encode এর মাধ্যমে ফাইল ডেটা নিন
        $file_data = $package_data['file_data'];
        // base64_decode-এর মাধ্যমে মূল বাইনারি ফাইল ডেটায় রূপান্তর করুন
        $file_data = base64_decode($file_data);
        // ডেটা ফেরত দিন
        return array(
             'file_name' => $file_name,
             'file_data' => $file_data,
         );
    }

    public static function encode($data)
    {
        // আপনি প্রয়োজন অনুযায়ী ক্লায়েন্টকে প্রেরিত তথ্য কোড করতে পারেন, এখানে কেবল টেক্সট হিসাবে ফিরিয়ে দেয়া হয়েছে
        return $data;
    }
}

সার্ভার প্রোটোকল ব্যবহার উদাহরণ

বিষয়: দ্বন্দ্ব বাইনরি আপলোড লেখার জন্য প্রয়োজন এবং এটি এমন একটি প্রোটোকল পরিবর্তন করতে দেয় যে প্রায় কোনও ব্যবসা কোড পরিবর্তন করতে হবে না

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('TextTransfer://0.0.0.0:8333');
// tmp-তে ফাইল সংরক্ষণ করুন
$worker->onMessage = function(TcpConnection $connection, $data)
{
    $save_path = '/tmp/'.$data['file_name'];
    file_put_contents($save_path, $data['file_data']);
    $connection->send("upload success. save path $save_path");
};

Worker::runAll();

ক্লায়েন্ট ফাইল textclient.php (এখানে php ব্যবহার করে ক্লায়েন্ট আপলোডের নকল করা)

<?php
/** ফাইল আপলোড ক্লায়েন্ট **/
// আপলোড ঠিকানা
$address = "127.0.0.1:8333";
// আপলোড ফাইলের পথ প্যারামিটার পরীক্ষা করুন
if(!isset($argv[1]))
{
   exit("use php client.php \$file_path\n");
}
// আপলোড ফাইলের পথ
$file_to_transfer = trim($argv[1]);
// আপলোডের ফাইল স্থানীয়ভাবে অস্তিত্বহীন 
if(!is_file($file_to_transfer))
{
    exit("$file_to_transfer not exist\n");
}
// সোকার সংযোগ তৈরি করুন
$client = stream_socket_client($address, $errno, $errmsg);
if(!$client)
{
    exit("$errmsg\n");
}
stream_set_blocking($client, 1);
// ফাইল নাম
$file_name = basename($file_to_transfer);
// ফাইল মৌলিক ডেটা
$file_data = file_get_contents($file_to_transfer);
// base64 কোডিং
$file_data = base64_encode($file_data);
// ডেটা প্যাকেজ
$package_data = array(
    'file_name' => $file_name,
    'file_data' => $file_data,
);
// প্রোটোকল প্যাকেজ json+newline
$package = json_encode($package_data)."\n";
// আপলোড সম্পন্ন করুন
fwrite($client, $package);
// ফলাফল মুদ্রণ করুন
echo fread($client, 8192),"\n";

ক্লায়েন্ট ব্যবহার উদাহরণ

কমান্ড লাইনে চালান php textclient.php <ফাইলের পথ>

যথা php textclient.php abc.jpg