websocket:数组转换成websocket数据

这是我写即时聊天遇到的问题。

如果是简单的即时聊天,可以直接返回字符串。但是我的聊天信息要从数据库获得,所以就要用到数组了。其实也很简单,就是把数组转换成json数据就可以了,然后再用websocket协议传过去。上代码

这是取出数据库的数据

  function get_message($sendid,$accessid)
  {
    $arr = '';
    mysql_select_db('newymj',$this->db);
    $sql = "select * from ymz_sendmsg limit 1,10";
    $res = mysql_query($sql);
    while($row = mysql_fetch_assoc($res))
    {
      $arr .= json_encode($row).'*';//转换json数据
    }
    return $arr;
  }

发送数据

 function send($client, $msg)
  {
    $msg = $this->frame($msg);
    socket_write($this->users[$client]['socket'], $msg, strlen($msg));

  }
  //转换websocket字符
  function frame($s)
  {
    $a = explode('*', $s);//每一行为一个单位发送,通过‘*’分割
    if (count($a) == 1) {
      return "\x81" . chr(strlen($a[0])) . $a[0];
    }
    $ns = "";
    foreach ($a as $o) {
      $ns .= "\x81" . chr(strlen($o)) . $o;
    }
    return $ns;
  }
前台代码

 ws.onmessage = function(e){
      var message =JSON.parse(e.data);
      alert(e.data);
    }

之所以要分片发送,是为了防止报错

WebSocket connection to 'ws://localhost:4000/' failed: Could not decode a text frame as UTF-8.

这个错误就是我把每行放到同一个数组,然后转换,就出现这个错误。网上说是因为数据太大的原因。所以我分片了。

如果有更好的方法,希望可以交流。

补充一下,因为websocket数据帧默认是125个字节,但是可以扩展

“负载数据”的长度,以字节为单位:如果0-125,这是负载长度。如果126,之后的两字节解释为一个16位的无符号整数是负载长度。如果127,之后的8字节解释为一个64位的无符号整数(最高有效位必须是0)是负载长度。多字节长度数量以网络字节顺序来表示。注意,在所有情况下,最小数量的字节必须用于编码长度,例如,一个124字节长的字符串的长度不能被编码为序列126,0,124。负载长度是“扩展数据”长度+“应用数据”长度。“扩展数据”长度可能是零,在这种情况下,负载长度是“应用数据”长度。

  foreach ($a as $o) {
      if(strlen($o)<=125)
      {
        $ns .= "\x81".chr(strlen($o)).$o;
      }
      else if(strlen($o)<=65535)
      {
        $ns .= "\x81".chr(126).pack("n", strlen($o)).$o;
      }
      else
      {
        $ns .= "\x81".char(127).pack("xxxxN", strlen($o)).$o;
      }      
    }



你可能感兴趣的:(PHP,websocket)