zoukankan      html  css  js  c++  java
  • PHP SOCKE实现聊天系统

    费话不多讲,具体看代码

     1.服务端实现

    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);    
            }    
                
            
        }

    回调

      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);
    }

    客户端实现

    <!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 + '说:
    ' + msg.text + '
    ';
            $('message').value += text;
            $('message').scrollTop = $('message').scrollHeight;
        }
        function updataUserNum(msg) {
            $('userNum').innerText = msg;
        }
        $('sub').addEventListener('click',sendMsg,false);
    })();
    </script>
    </body>
    </html>
  • 相关阅读:
    JAVA学习第五十四课 — IO流(八)打印流 &amp; 序列流
    jdbc框架 commons-dbutils+google guice+servlet 实现一个例子
    java ThreadLocal 理解
    jdbc框架 commons-dbutils的使用
    Java 集合系列06之 Vector详细介绍(源码解析)和使用示例
    Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
    Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)
    Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
    Java 集合系列02之 Collection架构
    Java 集合系列01之 总体框架
  • 原文地址:https://www.cnblogs.com/LXJ416/p/5656650.html
Copyright © 2011-2022 走看看