How can I send and receive WebSocket messages on the server side?

后端 未结 11 1893
轻奢々
轻奢々 2020-11-22 06:21
  • How can I send and receive messages on the server side using WebSocket, as per the protocol?

  • Why do I get seemingly random bytes at the server when

相关标签:
11条回答
  • 2020-11-22 06:30

    PHP Implementation:

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 06:32

    C++ Implementation (not by me) here. Note that when your bytes are over 65535, you need to shift with a long value as shown here.

    0 讨论(0)
  • 2020-11-22 06:34

    pimvdb's answer implemented in python:

    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
    

    An Example of usage:

    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', '!']
    
    0 讨论(0)
  • 2020-11-22 06:36

    Thank you for the answer, i would like to add onto hfern's(above) Python version to include the Sending function if any one is interested.

    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) 
    

    Usage for reading:

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

    Usage for writing:

    EncodeWebSockSend(sock,"hellooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo")
    
    0 讨论(0)
  • 2020-11-22 06:40

    In addition to the PHP frame encoding function, here follows a decode function:

    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;
    }
    

    I've implemented this and also other functions in an easy-to-use WebSocket PHP class here.

    0 讨论(0)
  • 2020-11-22 06:41

    JavaScript implementation:

    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;
    }
    
    0 讨论(0)
提交回复
热议问题