php 实现 websocket 握手成功后,第二次接收来自客户端消息乱码怎么解决??

客户端 websocketphp server 第一次握手成功后,第二次数据传输(数据尚未被解析)的过程中,输出的数据乱码,怎么解决??

clipboard.png

我直接输出客户端发送来的数据,结果却乱码:

clipboard.png

如何解决??


完整代码PHP:

class WebSocket {
    private $_res = null;
    public $isHandle = false;
    public $header = [];

    function __construct($ip , $port){
        $res = socket_create(AF_INET , SOCK_STREAM , SOL_TCP);

        socket_bind($res , $ip , $port);

        socket_listen($res);

        // socket_set_nonblock($res);

        $this->_res = $res;
    }

    public function listen(){
        $count = 1;

        $identifier = socket_accept($this->_res);

        while (true)
        {
            // 未握手,握手响应
            $data = socket_read($identifier , 1024);

            if (!$this->isHandle()) {
                $this->parseHeader($data);

                $response = $this->response();

                socket_write($identifier , $response);

                $this->isHandle = true;
            } else {
                // 握手成功后数据帧处理
                print_r($data);

                // print_r(mb_convert_encoding($data , 'gb2312' , 'utf-8'));
                // print_r(PHP_EOL);
                // $this->send($identifier , $data);
            }

            // usleep(16 * 1000);
            sleep(2);
        }
    }



    // 判断该资源是否已经握手过了
    public function isHandle():bool {
        return $this->isHandle;
    }

    // 解析请求头
    public function parseHeader(string $str = '') {
        $data = explode("\r\n" , $str);
        // print_r($data);

        $this->header = [];

        foreach ($data as $k => $v)
        {
            $line = trim($v);
            $line = str_replace('-' , '_' , $line);

            if ($k === 0) {
                $line = explode(' ' , $line);
                $this->header['method']   = $line[0];
                $this->header['path']     = $line[1];
                $this->header['protocol'] = $line[2];
            } else {
                $line = explode(':' , $line);
                $this->header[strtolower($line[0])] = ltrim($line[1]);
            }
        }
    }

    // 生成 key
    public function genKey(){
        // 参考 RFC 文档(Internet 标准 WebSocket 协议部分)
        $guid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
        $client_key = $this->header['sec_websocket_key'];
        $client_key = trim($client_key);
        $client_key .= $guid;
        $client_key = sha1($client_key , true);
        $client_key = base64_encode($client_key);

        return $client_key;
    }

    // 生成响应头
    public function response(){
        $key = $this->genKey();

        $h  = "HTTP/1.1 101 Switching Protocols\r\n";
        $h .= "Upgrade: websocket\r\n";
        $h .= "Connection: Upgrade\r\n";
        $h .= "Server: grayVTouch\r\n";
        $h .= "Sec-WebSocket-Version: 13\r\n";
        $h .= "Sec-WebSocket-Accept: {$key}\r\n";
        $h .= "\r\n\r\n";

        return $h;
    }
}

$ip = '0.0.0.0';
$port = 9160;
$ws = new WebSocket($ip , $port);
$ws->listen();

Js 代码

    var url = 'ws://192.168.150.133:9160';
    var ws = new WebSocket(url);

    ws.onopen = function(){
        console.log(this.readyState , 'open');
    };

    ws.onmessage = function(){
        console.log(event , event.data , 'receive msg');
    };

    ws.onclose = function(event){
        console.log(this.readyState , 'close');
    };
阅读 5.9k
1 个回答

你这干啥呢老大哥。
客户端是websocket。
你服务端是原始socket。

服务端少了一层websocket协议解析啊。
你输出的“乱码”,其实是websocket的握手包结构体。不是ASCII字符串啊。

http://www.phpbuilder.com/art...

如果你不想处理websocket协议的内部格式,可以用上面链接里的方式,使用别人写好的websocket封装

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题