这是我写即时聊天遇到的问题。
如果是简单的即时聊天,可以直接返回字符串。但是我的聊天信息要从数据库获得,所以就要用到数组了。其实也很简单,就是把数组转换成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).'*';//<span style="font-size:18px;color:#FF6666;">转换json数据</span>
}
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);//<span style="font-size:18px;color:#FF6666;">每一行为一个单位发送,通过‘*’分割</span>
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;
}
}