আমি কীভাবে সার্ভার সাইডে ওয়েবস্কট বার্তাগুলি প্রেরণ এবং গ্রহণ করতে পারি?


86
  • প্রোটোকল অনুযায়ী আমি কীভাবে ওয়েবস্কট ব্যবহার করে সার্ভার সাইডে বার্তা প্রেরণ ও গ্রহণ করতে পারি?

  • যখন আমি ব্রাউজার থেকে সার্ভারে ডেটা প্রেরণ করি তখন কেন আমি সার্ভারে আপাতদৃষ্টিতে এলোমেলো বাইট পেতে পারি? এটি কি কোনওভাবে এনকোড করা ডেটা?

  • সার্ভার the ক্লায়েন্ট এবং ক্লায়েন্ট → সার্ভার উভয় দিকনির্দেশে ফ্রেমিং কীভাবে কাজ করে?

উত্তর:


154

দ্রষ্টব্য: এটি কীভাবে খুব তুচ্ছ সার্ভার প্রয়োগ করতে হবে তা নির্দিষ্টভাবে ফ্রেমিং বিন্যাস অনুযায়ী ইনকামিং এবং আগত ওয়েবসকেট বার্তাগুলি পরিচালনা করতে পারে সে সম্পর্কে এটি কিছু ব্যাখ্যা এবং সিউডোকোড। এতে হ্যান্ডশেকিং প্রক্রিয়া অন্তর্ভুক্ত নয়। তদুপরি, এই উত্তরটি শিক্ষাগত উদ্দেশ্যে তৈরি করা হয়েছে; এটি একটি পূর্ণ বৈশিষ্ট্যযুক্ত বাস্তবায়ন নয়।

নির্দিষ্টকরণ (আরএফসি 6455)


বার্তা প্রেরণ করা হচ্ছে

(অন্য কথায়, সার্ভার-ব্রাউজার)

আপনি যে ফ্রেমগুলি প্রেরণ করছেন তা ওয়েবস্কট ফ্রেমিং বিন্যাস অনুযায়ী ফর্ম্যাট করা দরকার। বার্তা প্রেরণের জন্য, এই ফর্ম্যাটটি নিম্নরূপ:

  • একটি বাইট যা ডেটার ধরণ (এবং কিছু অতিরিক্ত তথ্য যা তুচ্ছ সার্ভারের সুযোগের বাইরে থাকে) ধারণ করে
  • একটি বাইট যা দৈর্ঘ্য ধারণ করে
  • দুটি বা আটটি বাইট যদি দৈর্ঘ্যটি দ্বিতীয় বাইটের সাথে মানানসই হয় না (দ্বিতীয় বাইটটি এমন একটি কোড যা বলা হয় দৈর্ঘ্যের জন্য কত বাইট ব্যবহৃত হয়)
  • আসল (কাঁচা) তথ্য

পাঠ্য ফ্রেমের জন্য প্রথম বাইটটি 1000 0001(বা 129) হবে ।

দ্বিতীয় বাইটটির প্রথম বিট সেট করা হয়েছে 0কারণ আমরা ডেটা এনকোড করছি না (সার্ভার থেকে ক্লায়েন্টে এনকোডিং বাধ্যতামূলক নয়)।

কাঁচা ডেটার দৈর্ঘ্য নির্ধারণ করা প্রয়োজন যাতে দৈর্ঘ্য বাইটগুলি সঠিকভাবে প্রেরণ করা যায়:

  • যদি 0 <= length <= 125, আপনার অতিরিক্ত বাইটের দরকার নেই
  • যদি 126 <= length <= 65535, আপনার দুটি অতিরিক্ত বাইট প্রয়োজন এবং দ্বিতীয় বাইট হয়126
  • যদি length >= 65536, আপনার আট অতিরিক্ত বাইট প্রয়োজন, এবং দ্বিতীয় বাইট হয়127

দৈর্ঘ্যটি আলাদা বাইটে কাটাতে হবে, যার অর্থ আপনাকে ডানদিকে বিট-শিফট করতে হবে (আট বিটের পরিমাণ সহ) এবং তারপরে কেবলমাত্র শেষ আটটি বিট ধরে রাখা হবে AND 1111 1111(যা 255)।

দৈর্ঘ্য বাইট (গুলি) পরে কাঁচা ডেটা আসে।

এটি নিম্নলিখিত সিউডোকোডের দিকে নিয়ে যায়:

bytesFormatted[0] = 129

indexStartRawData = -1 // it doesn't matter what value is
                       // set here - it will be set now:

if bytesRaw.length <= 125
    bytesFormatted[1] = bytesRaw.length

    indexStartRawData = 2

else if bytesRaw.length >= 126 and bytesRaw.length <= 65535
    bytesFormatted[1] = 126
    bytesFormatted[2] = ( bytesRaw.length >> 8 ) AND 255
    bytesFormatted[3] = ( bytesRaw.length      ) AND 255

    indexStartRawData = 4

else
    bytesFormatted[1] = 127
    bytesFormatted[2] = ( bytesRaw.length >> 56 ) AND 255
    bytesFormatted[3] = ( bytesRaw.length >> 48 ) AND 255
    bytesFormatted[4] = ( bytesRaw.length >> 40 ) AND 255
    bytesFormatted[5] = ( bytesRaw.length >> 32 ) AND 255
    bytesFormatted[6] = ( bytesRaw.length >> 24 ) AND 255
    bytesFormatted[7] = ( bytesRaw.length >> 16 ) AND 255
    bytesFormatted[8] = ( bytesRaw.length >>  8 ) AND 255
    bytesFormatted[9] = ( bytesRaw.length       ) AND 255

    indexStartRawData = 10

// put raw data at the correct index
bytesFormatted.put(bytesRaw, indexStartRawData)


// now send bytesFormatted (e.g. write it to the socket stream)

বার্তা গ্রহণ

(অন্য কথায়, ব্রাউজার-সার্ভার)

আপনি প্রাপ্ত ফ্রেমগুলি নিম্নলিখিত ফর্ম্যাটে রয়েছে:

  • এক বাইট যা তথ্যের ধরণ ধারণ করে
  • একটি বাইট যা দৈর্ঘ্য ধারণ করে
  • দৈর্ঘ্যটি দ্বিতীয় বাইটে ফিট না হলে দুটি বা আটটি অতিরিক্ত বাইট
  • চারটি বাইট যা মুখোশ (= ডিকোডিং কী)
  • আসল তথ্য

প্রথম বাইটটি সাধারণত কিছু যায় আসে না - আপনি যদি কেবল পাঠ্য প্রেরণ করেন তবে আপনি কেবল পাঠ্যের প্রকারটি ব্যবহার করছেন। এটি ক্ষেত্রে 1000 0001(বা 129) হবে ।

দ্বিতীয় বাইট এবং অতিরিক্ত দুটি বা আট বাইটের কিছু পার্সিং দরকার, কারণ আপনার দৈর্ঘ্যের জন্য কতগুলি বাইট ব্যবহার করা উচিত তা জানতে হবে (আসল ডেটা কোথায় শুরু হয় তা আপনার জানা দরকার)। দৈর্ঘ্য নিজেই সাধারণত প্রয়োজন হয় না কারণ আপনার কাছে ইতিমধ্যে ডেটা রয়েছে।

দ্বিতীয় বাইটের প্রথম বিটটি সর্বদা থাকে 1যার অর্থ ডেটাটি মাস্ক করা হয় (= এনকোডড)। ক্লায়েন্ট থেকে সার্ভারে থাকা বার্তাগুলি সর্বদা মুখোশযুক্ত। আপনাকে সেই প্রথম বিটটি সরিয়ে ফেলতে হবে secondByte AND 0111 1111। দুটি ক্ষেত্রে রয়েছে যে ফলস্বরূপ বাইটটি দৈর্ঘ্যের প্রতিনিধিত্ব করে না কারণ এটি দ্বিতীয় বাইটে ফিট করে না:

  • একটি দ্বিতীয় বাইট 0111 1110, অথবা 126, নিম্নলিখিত দুটি বাইট দৈর্ঘ্য জন্য ব্যবহার করা হয় এর মানে হল
  • 0111 1111বা এর দ্বিতীয় বাইট 127মানে নীচের আটটি বাইট দৈর্ঘ্যের জন্য ব্যবহৃত হয়

চারটি মাস্ক বাইট প্রেরণ করা প্রকৃত ডেটা ডিকোডিংয়ের জন্য ব্যবহৃত হয়। ডিকোডিংয়ের জন্য অ্যালগরিদমটি নিম্নরূপ:

decodedByte = encodedByte XOR masks[encodedByteIndex MOD 4]

যেখানে encodedByteডেটাতে মূল বাইট হয়, encodedByteIndexতা হল আসল তথ্যগুলির প্রথম বাইট থেকে বন্টন গণনার সূচক (অফসেট) , যা সূচকযুক্ত 0masksচারটি মাস্ক বাইট সমন্বিত একটি অ্যারে।

এটি ডিকোডিংয়ের জন্য নিম্নলিখিত সিউডোকোডের দিকে নিয়ে যায়:

secondByte = bytes[1]

length = secondByte AND 127 // may not be the actual length in the two special cases

indexFirstMask = 2          // if not a special case

if length == 126            // if a special case, change indexFirstMask
    indexFirstMask = 4

else if length == 127       // ditto
    indexFirstMask = 10

masks = bytes.slice(indexFirstMask, 4) // four bytes starting from indexFirstMask

indexFirstDataByte = indexFirstMask + 4 // four bytes further

decoded = new array

decoded.length = bytes.length - indexFirstDataByte // length of real data

for i = indexFirstDataByte, j = 0; i < bytes.length; i++, j++
    decoded[j] = bytes[i] XOR masks[j MOD 4]


// now use "decoded" to interpret the received data

1000 0001একটি পাঠ্য ফ্রেমের জন্য কেন (129)? বৈশিষ্ট বলেছেন বলে: %x1 denotes a text frame। সুতরাং এটি 0000 0001( 0x01), বা হওয়া উচিত ?
ডেনিস

4
@ ডেনিস: ফ্রেম অপকোডটি যেমন চশমাগুলির 0001সেই অংশের শিরোনামে রয়েছে: "ওপকোড: 4 বিট"। প্রথম বাইটে এফআইএন, আরএসভি 1-3 এবং অপকোড থাকে। এফআইএন হ'ল 1, আরএসভি 1৩- এ তিনটিই 0এবং অপকোড 0001যা 1000 0001প্রথম বাইটটি যুক্ত করে। এছাড়াও নির্দিষ্টকরণে শিল্পকর্মটি দেখুন যা দেখায় যে কীভাবে বাইটগুলি বিভিন্ন অংশে বিভক্ত হয়।
pimvdb

আপনার কাছে কয়েকটি লাইন রয়েছে যা সার্ভার-> ক্লায়েন্ট মডেলটিতে 'বাইটস ফরমেটেড [2] = (বাইটসরও.লেনথ >> 56) এবং 255' এর মতো পড়েন - আপনি কি আমার জন্য এটি ভেঙে ফেলতে আপত্তি করবেন? এবং আমার কাছে এটি একটি যৌক্তিক অপারেটর বলে মনে হচ্ছে তাই আমি আশা করতে পারি না যে এটির পরে একটি সংখ্যা রাখাই সি # তে আমার জন্য কিছু করবে। তেমনি, আমি নিশ্চিত না যে আপনার মার্কআপে ">>" কী নির্দেশ করবে বলে মনে করা হচ্ছে - তবে এটি সি # তে স্থানান্তর করে ... যা আমার কাছে তা বোঝায় ...: পি
ডিজিটালজেডি 805

যদি কেউ আমার পক্ষে এটি পরিষ্কার করে দিতে পারে তবে আমি উত্তর হিসাবে আমার সি # বাস্তবায়ন পোস্ট করে খুশি হব।
ডিজিটালজেদি 805

4
@ নিউভেক: তারা যা বোঝায় তা হ'ল মুখোশ বাইটগুলি অপ্রত্যাশিত হওয়া দরকার। যদি তারা অবিচল থাকে তবে তাদের মধ্যে খুব বেশি কিছু নেই। মূলত, যখন কোনও দূষিত ব্যবহারকারীর কাছে এক ধরণের ডেটা থাকে, তখন সে মুখোশ ছাড়া এটি ডিকোড করতে সক্ষম হবে না। যদি মুখোশের অবস্থানটি অনুমানযোগ্য না হয় তবে প্রকৃত সার্ভারের জন্য ডিকোড করা কিছুটা কঠিন :)
pimvdb

26

জাভা বাস্তবায়ন (যদি কারও প্রয়োজন হয়)

পড়া: সার্ভারে ক্লায়েন্ট

        int len = 0;            
        byte[] b = new byte[buffLenth];
        //rawIn is a Socket.getInputStream();
        while(true){
            len = rawIn.read(b);
            if(len!=-1){

                byte rLength = 0;
                int rMaskIndex = 2;
                int rDataStart = 0;
                //b[0] is always text in my case so no need to check;
                byte data = b[1];
                byte op = (byte) 127;
                rLength = (byte) (data & op);

                if(rLength==(byte)126) rMaskIndex=4;
                if(rLength==(byte)127) rMaskIndex=10;

                byte[] masks = new byte[4];

                int j=0;
                int i=0;
                for(i=rMaskIndex;i<(rMaskIndex+4);i++){
                    masks[j] = b[i];
                    j++;
                }

                rDataStart = rMaskIndex + 4;

                int messLen = len - rDataStart;

                byte[] message = new byte[messLen];

                for(i=rDataStart, j=0; i<len; i++, j++){
                    message[j] = (byte) (b[i] ^ masks[j % 4]);
                }

                parseMessage(new String(message)); 
                //parseMessage(new String(b));

                b = new byte[buffLenth];

            }
        }

লেখা: ক্লায়েন্ট থেকে সার্ভার

public void brodcast(String mess) throws IOException{
    byte[] rawData = mess.getBytes();

    int frameCount  = 0;
    byte[] frame = new byte[10];

    frame[0] = (byte) 129;

    if(rawData.length <= 125){
        frame[1] = (byte) rawData.length;
        frameCount = 2;
    }else if(rawData.length >= 126 && rawData.length <= 65535){
        frame[1] = (byte) 126;
        int len = rawData.length;
        frame[2] = (byte)((len >> 8 ) & (byte)255);
        frame[3] = (byte)(len & (byte)255); 
        frameCount = 4;
    }else{
        frame[1] = (byte) 127;
        int len = rawData.length;
        frame[2] = (byte)((len >> 56 ) & (byte)255);
        frame[3] = (byte)((len >> 48 ) & (byte)255);
        frame[4] = (byte)((len >> 40 ) & (byte)255);
        frame[5] = (byte)((len >> 32 ) & (byte)255);
        frame[6] = (byte)((len >> 24 ) & (byte)255);
        frame[7] = (byte)((len >> 16 ) & (byte)255);
        frame[8] = (byte)((len >> 8 ) & (byte)255);
        frame[9] = (byte)(len & (byte)255);
        frameCount = 10;
    }

    int bLength = frameCount + rawData.length;

    byte[] reply = new byte[bLength];

    int bLim = 0;
    for(int i=0; i<frameCount;i++){
        reply[bLim] = frame[i];
        bLim++;
    }
    for(int i=0; i<rawData.length;i++){
        reply[bLim] = rawData[i];
        bLim++;
    }

    out.write(reply);
    out.flush();

}

4
রিড অপারেশনের জন্য উপযুক্ত বাফার দৈর্ঘ্য কত হবে?
jackgerrits

দুর্ভাগ্যক্রমে, এটি কাজ করে না। আমি সবেমাত্র আমার প্রোগ্রামটিতে অকার্যকর সম্প্রচার (সার্ভার থেকে ক্লায়েন্ট) অনুলিপি করেছি। সকেট সফলভাবে সংযুক্ত হয়েছে, মেসেজটি সফলভাবে ব্রাউজারে প্রেরণ করা হয়েছে, তবে ব্রাউজারের দ্বারা কিছুই পাওয়া যায় নি।
নিক

18

জাভাস্ক্রিপ্ট বাস্তবায়ন:

function encodeWebSocket(bytesRaw){
    var bytesFormatted = new Array();
    bytesFormatted[0] = 129;
    if (bytesRaw.length <= 125) {
        bytesFormatted[1] = bytesRaw.length;
    } else if (bytesRaw.length >= 126 && bytesRaw.length <= 65535) {
        bytesFormatted[1] = 126;
        bytesFormatted[2] = ( bytesRaw.length >> 8 ) & 255;
        bytesFormatted[3] = ( bytesRaw.length      ) & 255;
    } else {
        bytesFormatted[1] = 127;
        bytesFormatted[2] = ( bytesRaw.length >> 56 ) & 255;
        bytesFormatted[3] = ( bytesRaw.length >> 48 ) & 255;
        bytesFormatted[4] = ( bytesRaw.length >> 40 ) & 255;
        bytesFormatted[5] = ( bytesRaw.length >> 32 ) & 255;
        bytesFormatted[6] = ( bytesRaw.length >> 24 ) & 255;
        bytesFormatted[7] = ( bytesRaw.length >> 16 ) & 255;
        bytesFormatted[8] = ( bytesRaw.length >>  8 ) & 255;
        bytesFormatted[9] = ( bytesRaw.length       ) & 255;
    }
    for (var i = 0; i < bytesRaw.length; i++){
        bytesFormatted.push(bytesRaw.charCodeAt(i));
    }
    return bytesFormatted;
}

function decodeWebSocket (data){
    var datalength = data[1] & 127;
    var indexFirstMask = 2;
    if (datalength == 126) {
        indexFirstMask = 4;
    } else if (datalength == 127) {
        indexFirstMask = 10;
    }
    var masks = data.slice(indexFirstMask,indexFirstMask + 4);
    var i = indexFirstMask + 4;
    var index = 0;
    var output = "";
    while (i < data.length) {
        output += String.fromCharCode(data[i++] ^ masks[index++ % 4]);
    }
    return output;
}

4
সম্ভবত লক্ষণীয় যে জাভাস্ক্রিপ্ট আসলে এর চেয়ে বড় সংখ্যার সাথে স্থানান্তরিত সমর্থন করে না 2^31 - 1
pimvdb

13

সি # বাস্তবায়ন

ব্রাউজার -> সার্ভার

    private String DecodeMessage(Byte[] bytes)
    {
        String incomingData = String.Empty;
        Byte secondByte = bytes[1];
        Int32 dataLength = secondByte & 127;
        Int32 indexFirstMask = 2;
        if (dataLength == 126)
            indexFirstMask = 4;
        else if (dataLength == 127)
            indexFirstMask = 10;

        IEnumerable<Byte> keys = bytes.Skip(indexFirstMask).Take(4);
        Int32 indexFirstDataByte = indexFirstMask + 4;

        Byte[] decoded = new Byte[bytes.Length - indexFirstDataByte];
        for (Int32 i = indexFirstDataByte, j = 0; i < bytes.Length; i++, j++)
        {
            decoded[j] = (Byte)(bytes[i] ^ keys.ElementAt(j % 4));
        }

        return incomingData = Encoding.UTF8.GetString(decoded, 0, decoded.Length);
    }

সার্ভার -> ব্রাউজার

    private static Byte[] EncodeMessageToSend(String message)
    {
        Byte[] response;
        Byte[] bytesRaw = Encoding.UTF8.GetBytes(message);
        Byte[] frame = new Byte[10];

        Int32 indexStartRawData = -1;
        Int32 length = bytesRaw.Length;

        frame[0] = (Byte)129;
        if (length <= 125)
        {
            frame[1] = (Byte)length;
            indexStartRawData = 2;
        }
        else if (length >= 126 && length <= 65535)
        {
            frame[1] = (Byte)126;
            frame[2] = (Byte)((length >> 8) & 255);
            frame[3] = (Byte)(length & 255);
            indexStartRawData = 4;
        }
        else
        {
            frame[1] = (Byte)127;
            frame[2] = (Byte)((length >> 56) & 255);
            frame[3] = (Byte)((length >> 48) & 255);
            frame[4] = (Byte)((length >> 40) & 255);
            frame[5] = (Byte)((length >> 32) & 255);
            frame[6] = (Byte)((length >> 24) & 255);
            frame[7] = (Byte)((length >> 16) & 255);
            frame[8] = (Byte)((length >> 8) & 255);
            frame[9] = (Byte)(length & 255);

            indexStartRawData = 10;
        }

        response = new Byte[indexStartRawData + length];

        Int32 i, reponseIdx = 0;

        //Add the frame bytes to the reponse
        for (i = 0; i < indexStartRawData; i++)
        {
            response[reponseIdx] = frame[i];
            reponseIdx++;
        }

        //Add the data bytes to the response
        for (i = 0; i < length; i++)
        {
            response[reponseIdx] = bytesRaw[i];
            reponseIdx++;
        }

        return response;
    }

4
ডিকোড ফাংশনটি সর্বদা আমার নির্দিষ্ট বার্তাটি এখানে আমার মতো অপরিজ্ঞাত পরিশিষ্টের সাথে ফিরিয়ে দেয় test�c=ܝX[যেখানে "পরীক্ষা" আমার বার্তা। অন্য অংশটি কী থেকে আসছে?
স্নিকব্র্যাক

4
দেরী উত্তর দেওয়ার জন্য দুঃখিত। ওয়েব সকেট চেষ্টা করার জন্য আমি একটি ছোট সি # অ্যাপ্লিকেশন (কনসোল এবং ওয়েব) তৈরি করেছি। এটি কোড করে কীভাবে তা দেখতে আপনি এগুলি এখান থেকে ডাউনলোড করতে পারেন। লিঙ্ক: dropbox.com/s/gw8hjsov1u6f7c0/Web%20Sockets.rar?dl=0
Nitij

এটি আমার পক্ষে বড় বার্তাগুলিতে ব্যর্থ হয়েছিল। আমি দৈর্ঘ্য> 65535 কোডটি এর সাথে প্রতিস্থাপন করেছি: var l = রূপান্তর TToUInt64 (দৈর্ঘ্য); var b = BitConverter.GetBytes (l); অ্যারে। বিপরীত (খ, 0, খ। দৈর্ঘ্য); বি.কপিটো (ফ্রেম, 2); ... যা স্থির জিনিস আছে বলে মনে হচ্ছে।
শান

ভাল করেছ. কেবল একটি জিনিস: ডিকোডমেজেজে আমি পেওলোড দৈর্ঘ্যের ডেটার উপর ভিত্তি করে "ডিকোডড" অ্যারের দৈর্ঘ্য গণনা করছি যা ডেটাফ্রেমে "বাইটস" অ্যারের দৈর্ঘ্যের সাথে অন্তর্ভুক্ত রয়েছে অ্যারের দৈর্ঘ্য সঠিক হতে পারে না। "বাইটস" অ্যারের দৈর্ঘ্য স্ট্রিমটি যেভাবে পড়ছে তার উপর নির্ভর করে।
ব্যবহারকারী 1011138

@ সিয়েন আপনি কি বড় বার্তার সমস্যা সমাধানের জন্য আমাকে আপনার পুরো উদাহরণটি দেখাতে পারেন? আমি আপনার নমুনায় কোডটি পরিবর্তন করতে পারি না।
আলী ইউসফি

6

পাইমভডিবির উত্তর পাইথনে প্রয়োগ করা হয়েছে:

def DecodedCharArrayFromByteStreamIn(stringStreamIn):
    #turn string values into opererable numeric byte values
    byteArray = [ord(character) for character in stringStreamIn]
    datalength = byteArray[1] & 127
    indexFirstMask = 2 
    if datalength == 126:
        indexFirstMask = 4
    elif datalength == 127:
        indexFirstMask = 10
    masks = [m for m in byteArray[indexFirstMask : indexFirstMask+4]]
    indexFirstDataByte = indexFirstMask + 4
    decodedChars = []
    i = indexFirstDataByte
    j = 0
    while i < len(byteArray):
        decodedChars.append( chr(byteArray[i] ^ masks[j % 4]) )
        i += 1
        j += 1
    return decodedChars

ব্যবহারের একটি উদাহরণ:

fromclient = '\x81\x8c\xff\xb8\xbd\xbd\xb7\xdd\xd1\xd1\x90\x98\xea\xd2\x8d\xd4\xd9\x9c'
# this looks like "?ŒOÇ¿¢gÓ ç\Ð=«ož" in unicode, received by server
print DecodedCharArrayFromByteStreamIn(fromclient)
# ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!']

আমি আপনার কোডটি আমার স্ক্রিপ্টে ব্যবহার করার চেষ্টা করেছি, তবে কোনও সাফল্য নেই। আপনি সম্ভবত সাহায্য করতে সক্ষম হতে পারে? stackoverflow.com/questions/43748377/…
ইয়াক

5

পিএইচপি ফ্রেম এনকোডিং ফাংশন ছাড়াও, এখানে একটি ডিকোড ফাংশন অনুসরণ করা হয়েছে:

function Decode($M){
    $M = array_map("ord", str_split($M));
    $L = $M[1] AND 127;

    if ($L == 126)
        $iFM = 4;
    else if ($L == 127)
        $iFM = 10;
    else
        $iFM = 2;

    $Masks = array_slice($M, $iFM, 4);

    $Out = "";
    for ($i = $iFM + 4, $j = 0; $i < count($M); $i++, $j++ ) {
        $Out .= chr($M[$i] ^ $Masks[$j % 4]);
    }
    return $Out;
}

আমি একটি সহজ-থেকে-ব্যবহার WebSocket এর পিএইচপি ক্লাসে এই এবং অন্যান্য কার্যাবলী প্রয়োগ করেছি এখানে


4

পিএইচপি বাস্তবায়ন:

function encode($message)
{
    $length = strlen($message);

    $bytesHeader = [];
    $bytesHeader[0] = 129; // 0x1 text frame (FIN + opcode)

    if ($length <= 125) {
            $bytesHeader[1] = $length;
    } else if ($length >= 126 && $length <= 65535) {
            $bytesHeader[1] = 126;
            $bytesHeader[2] = ( $length >> 8 ) & 255;
            $bytesHeader[3] = ( $length      ) & 255;
    } else {
            $bytesHeader[1] = 127;
            $bytesHeader[2] = ( $length >> 56 ) & 255;
            $bytesHeader[3] = ( $length >> 48 ) & 255;
            $bytesHeader[4] = ( $length >> 40 ) & 255;
            $bytesHeader[5] = ( $length >> 32 ) & 255;
            $bytesHeader[6] = ( $length >> 24 ) & 255;
            $bytesHeader[7] = ( $length >> 16 ) & 255;
            $bytesHeader[8] = ( $length >>  8 ) & 255;
            $bytesHeader[9] = ( $length       ) & 255;
    }

    $str = implode(array_map("chr", $bytesHeader)) . $message;

    return $str;
}

4

উত্তরের জন্য আপনাকে ধন্যবাদ, আমি যদি আগ্রহী হন তবে প্রেরণ ফাংশনটি অন্তর্ভুক্ত করার জন্য পাইফনের সংস্করণটি হিফেরনে (উপরে) যুক্ত করতে চাই ।

def DecodedWebsockRecieve(stringStreamIn):
    byteArray =  stringStreamIn 
    datalength = byteArray[1] & 127
    indexFirstMask = 2 
    if datalength == 126:
        indexFirstMask = 4
    elif datalength == 127:
        indexFirstMask = 10
    masks = [m for m in byteArray[indexFirstMask : indexFirstMask+4]]
    indexFirstDataByte = indexFirstMask + 4
    decodedChars = []
    i = indexFirstDataByte
    j = 0
    while i < len(byteArray):
        decodedChars.append( chr(byteArray[i] ^ masks[j % 4]) )
        i += 1
        j += 1
    return ''.join(decodedChars)

def EncodeWebSockSend(socket,data):
    bytesFormatted = []
    bytesFormatted.append(129)

    bytesRaw = data.encode()
    bytesLength = len(bytesRaw)
    if bytesLength <= 125 :
        bytesFormatted.append(bytesLength)
    elif bytesLength >= 126 and bytesLength <= 65535 :
        bytesFormatted.append(126)
        bytesFormatted.append( ( bytesLength >> 8 ) & 255 )
        bytesFormatted.append( bytesLength & 255 )
    else :
        bytesFormatted.append( 127 )
        bytesFormatted.append( ( bytesLength >> 56 ) & 255 )
        bytesFormatted.append( ( bytesLength >> 48 ) & 255 )
        bytesFormatted.append( ( bytesLength >> 40 ) & 255 )
        bytesFormatted.append( ( bytesLength >> 32 ) & 255 )
        bytesFormatted.append( ( bytesLength >> 24 ) & 255 )
        bytesFormatted.append( ( bytesLength >> 16 ) & 255 )
        bytesFormatted.append( ( bytesLength >>  8 ) & 255 )
        bytesFormatted.append( bytesLength & 255 )

    bytesFormatted = bytes(bytesFormatted)
    bytesFormatted = bytesFormatted + bytesRaw
    socket.send(bytesFormatted) 

পড়ার জন্য ব্যবহার:

bufSize = 1024     
read = DecodedWebsockRecieve(socket.recv(bufSize))

লেখার জন্য ব্যবহার:

EncodeWebSockSend(sock,"hellooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")

2

গো প্রয়োগে

এনকোড অংশ (সার্ভার -> ব্রাউজার)

func encode (message string) (result []byte) {
  rawBytes := []byte(message)
  var idxData int

  length := byte(len(rawBytes))
  if len(rawBytes) <= 125 { //one byte to store data length
    result = make([]byte, len(rawBytes) + 2)
    result[1] = length
    idxData = 2
  } else if len(rawBytes) >= 126 && len(rawBytes) <= 65535 { //two bytes to store data length
    result = make([]byte, len(rawBytes) + 4)
    result[1] = 126 //extra storage needed
    result[2] = ( length >> 8 ) & 255
    result[3] = ( length      ) & 255
    idxData = 4
  } else {
    result = make([]byte, len(rawBytes) + 10)
    result[1] = 127
    result[2] = ( length >> 56 ) & 255
    result[3] = ( length >> 48 ) & 255
    result[4] = ( length >> 40 ) & 255
    result[5] = ( length >> 32 ) & 255
    result[6] = ( length >> 24 ) & 255
    result[7] = ( length >> 16 ) & 255
    result[8] = ( length >>  8 ) & 255
    result[9] = ( length       ) & 255
    idxData = 10
  }

  result[0] = 129 //only text is supported

  // put raw data at the correct index
  for i, b := range rawBytes {
    result[idxData + i] = b
  }
  return
}

ডিকোড অংশ (ব্রাউজার -> সার্ভার)

func decode (rawBytes []byte) string {
  var idxMask int
  if rawBytes[1] == 126 {
    idxMask = 4
  } else if rawBytes[1] == 127 {
    idxMask = 10
  } else {
    idxMask = 2
  }

  masks := rawBytes[idxMask:idxMask + 4]
  data := rawBytes[idxMask + 4:len(rawBytes)]
  decoded := make([]byte, len(rawBytes) - idxMask + 4)

  for i, b := range data {
    decoded[i] = b ^ masks[i % 4]
  }
  return string(decoded)
}

2

ক্লোজার, ডিকোড ফাংশনটি ধরে নেয় ফ্রেমের মানচিত্র হিসাবে প্রেরণ করা হয়েছে {:data byte-array-buffer :size int-size-of-buffer}কারণ আপনার ইনপুটস্ট্রিমের খাঁটি আকারের উপর নির্ভর করে প্রকৃত আকার বাইট-অ্যারের মতো একই আকারের নাও হতে পারে।

কোড এখানে পোস্ট হয়েছে: https://gist.github.com/viperscape/8918565

(defn ws-decode [frame]
  "decodes websocket frame"
  (let [data (:data frame)
        dlen (bit-and (second data) 127)
        mstart (if (== dlen 127) 10 (if (== dlen 126) 4 2))
        mask (drop 2 (take (+ mstart 4) data))
        msg (make-array Byte/TYPE (- (:size frame) (+ mstart 4)))]
   (loop [i (+ mstart 4), j 0]
      (aset-byte msg j (byte (bit-xor (nth data i) (nth mask (mod j 4)))))
      (if (< i (dec(:size frame))) (recur (inc i) (inc j))))
    msg))

(defn ws-encode [data]
  "takes in bytes, return websocket frame"
  (let [len (count data)
        blen (if (> len 65535) 10 (if (> len 125) 4 2))
        buf (make-array Byte/TYPE (+ len blen))
        _ (aset-byte buf 0 -127) ;;(bit-or (unchecked-byte 0x80) 
                                           (unchecked-byte 0x1)
        _ (if (= 2 blen) 
            (aset-byte buf 1 len) ;;mask 0, len
            (do
              (dorun(map #(aset-byte buf %1 
                      (unchecked-byte (bit-and (bit-shift-right len (*(- %2 2) 8))
                                               255)))
                      (range 2 blen) (into ()(range 2 blen))))
              (aset-byte buf 1 (if (> blen 4) 127 126))))
        _ (System/arraycopy data 0 buf blen len)]
    buf))

0

সি ++ বাস্তবায়ন (আমার দ্বারা নয়) এখানে । লক্ষ্য করুন যখন আপনার বাইট 65535 ধরে আছে, আপনি হিসাবে দেখানো একটি দীর্ঘ মান নামান প্রয়োজন এখানে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.