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>
  • 相关阅读:
    Spring Boot 使用 Dom4j XStream 操作 Xml
    Spring Boot 使用 JAX-WS 调用 WebService 服务
    Spring Boot 使用 CXF 调用 WebService 服务
    Spring Boot 开发 WebService 服务
    Spring Boot 中使用 HttpClient 进行 POST GET PUT DELETE
    Spring Boot Ftp Client 客户端示例支持断点续传
    Spring Boot 发送邮件
    Spring Boot 定时任务 Quartz 使用教程
    Spring Boot 缓存应用 Memcached 入门教程
    ThreadLocal,Java中特殊的线程绑定机制
  • 原文地址:https://www.cnblogs.com/LXJ416/p/5656650.html
Copyright © 2011-2022 走看看