PHP SOCKE實現聊天系統

費話很少講,具體看代碼javascript

 1.服務端實現css

class Ws{
    
    private $host = '127.0.0.1';
    private $port = 8080;
    private $maxuser = 10;
    private $socket;
    public $accept = [];
    private $isHand = [];
    private $cycle = [];
    public function __construct($host,$port,$maxuser)
    {
        $this->host = $host;
        $this->port = $port;
        $this->maxuser = $maxuser;
    }
    
    public  function start()
    {
        // 建立一個Socket
        $this->socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
         //容許使用本地地址        
        socket_set_option($this->socket,SOL_SOCKET,SO_REUSEADDR,TRUE);
        // 綁定地址和端口
        socket_bind($this->socket,$this->host,$this->port);
        //偵聽
        socket_listen($this->socket,$this->maxuser);
        while(True){
            $this->cycle = $this->accept;
            $this->cycle[] = $this->socket;
            //阻塞用,有新鏈接時纔會結束
            socket_select($this->cycle, $write, $except, null);
            //輪詢
            foreach($this->cycle as $key =>$v){
                
                if($v === $this->socket){
                    //當接受一個Socket不成功時,繼續下一個
                    if(($accept = socket_accept($v))<0){
                        continue;
                    }
                    //添加到循環池
                    $this->add_accept($accept);
                    continue;
                }
                
                // 得到當前鏈接健值 
                $index = array_search($v,$this->accept);
                
                if($index === null){
                    continue;
                }
                
                // 接受客戶端數據
                if( !@socket_recv($v,$data,1024,0) || !$data){
                    
                    $this->close($v);
                    continue;
                }
                
                // 握手併發送用戶鏈接數
                if(!$this->isHand[$index]){
                    $this->upgrade($v,$data,$index);
                    call_user_func_array('user_add_callback',array($this));
                    continue;
                }
                $data = $this->decode($data);
                // 發送數據
                call_user_func_array('send_callback', array($data, $index, $this));
            }    
            sleep(1);    
        }    
            
        
    }

回調html

  function send_callback($data, $index, $ws) {
    $data = json_encode(array(
                        'text' => $data,
                        'user' => $index,
                        ));
    send_to_all($data, 'text', $ws);
}

function send_to_all($data, $type, $ws){
    $res = array(
            'msg' => $data,
            'type' => $type,
            );
    $res = json_encode($res);
    $res = $ws->frame($res);
    print_r($ws->accept);
    foreach ($ws->accept as $key => $value) {
        socket_write($value, $res, strlen($res));
    }
}

function close_callback($ws) {
    $data = count($ws->accept);
    send_to_all($data, 'num', $ws);
}

function user_add_callback($ws) {
    $data = count($ws->accept);
     send_to_all($data, 'num', $ws);
}

 

 

 

 

客戶端實現java

<!DOCTYPE html>
<html dir="ltr" lang="zh" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>websocket聊天室</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">

</head>
<body>
<div class="container">
    <p>在線人數<span id="userNum"></span></p>
    <textarea id="message" rows="10"></textarea>
    <div class="send">
        <p><textarea id="input" placeholder="請輸入要發送的內容"></textarea></p>
        <p><button type="button" class="btn btn-primary" id="sub">發送</button></p>
    </div>
</div>
<script type="text/javascript">
(function(){
    var $ = function(id){return document.getElementById(id) || null;}
    var wsServer = 'ws://127.0.0.1:8080'; 
    var ws = new WebSocket(wsServer);
    var isConnect = false;
    ws.onopen = function (evt) { onOpen(evt) }; 
    ws.onclose = function (evt) { onClose(evt) }; 
    ws.onmessage = function (evt) { onMessage(evt) }; 
    ws.onerror = function (evt) { onError(evt) }; 
    function onOpen(evt) { 
        console.log("鏈接服務器成功");
        isConnect = true;
    } 
    function onClose(evt) { 
        //console.log("Disconnected"); 
    } 
    function onMessage(evt) {
        var data = JSON.parse(evt.data);
        switch (data.type) {
            case 'text':
                addMsg(data.msg);
                break;
            case 'num' :
                updataUserNum(data.msg);
                break;
        }
        
        console.log('Retrieved data from server: ' + evt.data);
    }
    function onError(evt) { 
        //console.log('Error occured: ' + evt.data); 
    }
    function sendMsg() {
        if(isConnect){
            ws.send($('input').value);
            $('input').value = '';
        }
    }
    function addMsg(msg) {
        msg = JSON.parse(msg);
        var text = '用戶' + msg.user + '說:\n' + msg.text + '\n';
        $('message').value += text;
        $('message').scrollTop = $('message').scrollHeight;
    }
    function updataUserNum(msg) {
        $('userNum').innerText = msg;
    }
    $('sub').addEventListener('click',sendMsg,false);
})();
</script>
</body>
</html>
相關文章
相關標籤/搜索