php websocket 客服聊天系统

 

<?php
header("Content-type: text/html; charset=utf-8");
/*
创建类websocket($config); 
$config结构: 
$config=array( 
  'address'=>'192.168.0.200',//绑定地址 
  'port'=>'8000',//绑定端口 
  'event'=>'WSevent',//回调函数的函数名 
  'log'=>true,//命令行显示记录 
); 
  
回调函数返回数据格式 
function WSevent($type,$event) 
  
$type字符串 事件类型有以下三种 
in  客户端进入 
out 客户端断开 
msg 客户端消息到达 
均为小写 
  
$event 数组 
$event['k']内置用户列表的userid; 
$event['sign']客户标示 
$event['msg']收到的消息 $type='msg'时才有该信息 
  
方法: 
run()运行 
search(标示)遍历取得该标示的id 
close(标示)断开连接 
write(标示,信息)推送信息 
idwrite(id,信息)推送信息 
  
属性: 
$users 客户列表 
结构: 
$users=array( 
[用户id]=>array('socket'=>[标示],'hand'=[是否握手-布尔值]), 
[用户id]=>arr..... 
) 
*/
class websocket {
    public $log;
    public $event;
    public $signets;
    public $users;
    public $master;
    private $sda = array(); //已接收的数据
    private $slen = array(); //数据总长度
    private $sjen = array(); //接收数据的长度
    private $ar = array(); //加密key
    private $n = array();
    public function __construct($config) {
        if (substr(php_sapi_name(), 0, 3) !== 'cli') {
            die("请通过命令行模式运行!");
        }
        // error_reporting(E_ALL ^ E_NOTICE);
        // error_reporting(E_ALL ^ E_WARNING);
        //error_reporting(0);
        //set_time_limit(0);
        ob_implicit_flush();
        $this->event = $config['event'];
        $this->log = $config['log'];
        $this->master = $this->WebSocket($config['address'], $config['port']);
        $this->sockets = array((string)$this->master => $this->master);
    }
    public function WebSocket($address, $port) {
        $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
        socket_bind($server, $address, $port);
        socket_listen($server);
        $this->log('开始监听: ' . $address . ' : ' . $port);
        return $server;
    }
    public function run() {
        while (true) {
            $changes = $this->sockets;
            @socket_select($changes, $write = NULL, $except = NULL, NULL);
            foreach ($changes as $sign) {
                if ($sign == $this->master) {
                    $client = socket_accept($this->master);
                    if ($client < 0) {
                        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
                        break;
                    }
                    $this->sockets[(string)$client] = $client;
                    $user = array('socket' => $client, 'hand' => false,);
                    $this->users[(string)$client] = $user;
                    $k = $this->search($client);
                    $eventreturn = array('k' => $k, 'sign' => $sign);
                    $this->eventoutput('in', $eventreturn);
                    //$this->handshake((string)$sign,1);
                    
                } else {
                    $len = 0;
                    $buffer = '';
                    //读取该socket的信息,注意:第二个参数是引用传参即接收数据,第三个参数是接收数据的长度
                    do {
                        $l = socket_recv($sign, $buf, 1024, 0);
                        $len+= $l;
                        $buffer.= $buf;
                    } while ($l == 1024);
                    /*
                    $len = socket_recv($sign, $buffer, 2222048, 0);
                    if ($len < 0) {
                    echo "socket_recv() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
                    break;
                    }*/
                    $k = $this->search($sign);
                    if ($len < 7) {
                        $this->close($sign);
                        $eventreturn = array('k' => (string)$sign, 'sign' => $sign);
                        $this->eventoutput('out', $eventreturn);
                        continue;
                    }
                    if (!$this->users[(string)$sign]['hand']) { //没有握手进行握手
                        $this->handshake($sign, $buffer);
                    } else {
                        //$buffer = $this->uncode($buff
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值