°Ù·Ö°ÙÔ´ÂëÍø-Èý¨Õ¾±äµÃÈç´Ë¼òµ¥£¡ µÇ¼ ×¢²á Ç©µ½Áì½ð±Ò£¡

Ö÷Ò³ | ÈçºÎÉý¼¶VIP | TAG±êÇ©

µ±Ç°Î»ÖÃ: Ö÷Ò³>ÍøÕ¾½Ì³Ì>ÍøÒ³ÖÆ×÷> ·ÖÏíPHPɨÂëµÇ¼µÀÀí¼°ÊµÏÖ°ì·¨
·ÖÏíÎÄÕµ½£º

·ÖÏíPHPɨÂëµÇ¼µÀÀí¼°ÊµÏÖ°ì·¨

·¢²¼Ê±¼ä£º09/01 À´Ô´£ºÎ´Öª ä¯ÀÀ£º ¹Ø¼ü´Ê£º
ÓÉÓÚɨÂëµÇ¼±ÈÕ˺ÅÃÜÂëµÇ¼¸üÀû±ã¡¢¿ìËÙ¡¢ÁéÃô£¬ÔÚʵ¼ÊʹÓÃÖиüÊܵ½»áÔ±µÄ»¶Ó­¡£

±¾ÎÄÖ÷Òª½éÉÜÁËɨÂëµÇ¼µÄµÀÀí¼°ÍÅÌåÁ÷³Ì£¬°üÀ¨Á˶þάÂëµÄÉú³É/ÁÔÈ¡¡¢¹ýÆÚʧЧµÄ´¦ÖᢵǼ״̬µÄ¼àÌý¡£

ɨÂëµÇ¼µÄµÀÀí

ÍÅÌåÁ÷³Ì

ΪÀû±ã¶®µÃ£¬ÎÒ¼ò±ã»­ÁËÒ»¸ö UML ʱÐòͼ£¬ÓÃÒÔÃèдɨÂëµÇ¼µÄ´óÖÂÁ÷³Ì£¡

×ܽáÏÂÖÐÐÄÁ÷³Ì£º

  1. ¿ÒÇóÒµÎñЧÀÍÆ÷ÁÔÈ¡ÓÃÒԵǼµÄ¶þάÂëºÍ UUID¡£

  2. ͨ¹ý websocket Á¬½Ó socket ЧÀÍÆ÷£¬²¢°´Ê±(ʱ¼ä¼ä¸ô¸ù¾ÝЧÀÍÆ÷ÅäÖÃʱ¼äµ÷Õû)·¢ËÍÐÄÌø±£³ÖÁ¬½Ó¡£

  3. »áԱͨ¹ý APP ɨÃè¶þάÂ룬·¢ËÍ¿ÒÇóµ½ÒµÎñЧÀÍÆ÷´¦ÖõǼ¡£°´ÕÕ UUID É趨µÇ¼½á¹û¡£

  4. socket ЧÀÍÆ÷ͨ¹ý¼àÌýÁÔÈ¡µÇ¼½á¹û£¬´´Á¢ session Êý¾Ý£¬°´ÕÕ UUID ÍÆË͵ǼÊý¾Ýµ½»áÔ±ÔĶÁÆ÷¡£

  5. »áÔ±µÇ¼³É¹¦£¬Ð§ÀÍÆ÷Ö÷¶¯½«¸Ã socker Á¬½Ó´ÓÁ¬½Ó³ØÖÐÌÞ³ý£¬¸Ã¶þάÂëʧЧ¡£

¹ØÓÚ¿Í»§¶Ë±êʶ

Ò²¾ÍÊÇ UUID£¬ÕâÊǹᴩÕû¸öÁ÷³ÌµÄŦ´ø£¬Ò»¸ö±Õ»·µÇ¼Àú³Ì£¬Ã¿Ò»²½ÒµÎñ´¦Öö¼ÊÇ»·ÈÆ¸Ã´ÎµÄ UUD Í£Ö¹´¦Öõġ£UUID µÄÉú³ÉÓа´ÕÕ session_id µÄÒ²Óа´ÕÕ¿Í»§¶Ë ip µØÖ·µÄ¡£¸öÈË»¹Êdz«Òéÿ¸ö¶þάÂ붼ÓжÀ×﵀ UUID£¬ÊÊÓô¦¾°¸ü¹ãһЩ£¡

¹ØÓÚÇ°¶ËºÍЧÀÍÆ÷ͨѶ

Ç°¶Ë±Ø¶¨ÊÇÒªºÍЧÀÍÆ÷±£³Ö²»¶ÏͨѶµÄ£¬ÓÃÒÔÁÔÈ¡µÇ¼½á¹ûºÍ¶þάÂë״̬¡£¿´ÁËÏÂÍøÉϵÄһЩʵÏÖ·½°¸£¬¸ù±¾¸÷¸ö·½°¸¶¼ÓÐÓõģºÂÖѯ¡¢³¤ÂÖѯ¡¢³¤Á´½Ó¡¢websocket¡£Ò²²»¿Ë²»¼°±Ø¶¨µÄ˵Äĸö·½°¸ºÃÄĸö·½°¸²»ºÃ£¬Ö»ÄÜ˵Äĸö·½°¸¸üÊÊÓÃÓÚµ±Ç°ÀûÓó¡¾°¡£¸öÈ˱ÈÁ¦³«ÒéʹÓó¤ÂÖѯ¡¢websocket ÕâÖÖ±ÈÁ¦½ÚԼЧÀÍÆ÷»úÄܵķ½°¸¡£

¹ØÓÚƽ°²ÐÔ

ɨÂëµÇ¼µÄºÃ´¦²»ÑÔ¶øÓ÷£¬Ò»ÊÇÈËÐÔ»¯£¬ÔÙ¾ÍÊÇ·ÀÖ¹ÃÜÂë×ß©¡£µ«ÊÇз½Ê½µÄ½ÓÈ룬ÍùÍùÒ²Åã°é×ÅеķçÏÕ¡£ËùÒÔ£¬ºÜÓбØÒªÔÙÍÅÌåÀú³ÌÖвμÓÇ¡µ±µÄƽ°²»úÖÆ¡£ÀýÈ磺

  • Ç¿ÆÈ HTTPS ºÍ̸
  • ¶ÌÆÚÁîÅÆ
  • Êý¾ÝÇ©Ãû
  • Êý¾Ý¼ÓÃÜ

ɨÂëµÇ¼µÄÀú³ÌÑÝʾ

´úÂëʵÏÖºÍÔ´ÂëºóÃæ»á¸ø³ö¡£

¿ªÆô Socket ЧÀÍÆ÷

°Ý·ÃµÇ¼ҳÃæ

¿ÉÒÔ¿´µ½»áÔ±¿ÒÇóµÄ¶þάÂë×ÊÔ´£¬²¢ÁÔÈ¡µ½ÁË qid ¡£

ÁÔÈ¡¶þάÂëʱºò»á´´Á¢ÏìÓ¦»º´æ£¬²¢É趨¹ýÆÚʱ¼ä£º

Ö®ºó»áÁ¬½Ó socket ЧÀÍÆ÷£¬°´Ê±·¢ËÍÐÄÌø¡£

´Ëʱ socket ЧÀÍÆ÷»áÓÐÏìÓ¦Á¬½ÓÈÕÖ¾Êä³ö£º

»áԱʹÓà APP ɨÂë²¢ÊÚȨ

ЧÀÍÆ÷ÑéÖ¤²¢´¦ÖõǼ£¬´´Á¢ session£¬´´Á¢¶ÔÓ¦µÄ»º´æ£º

Socket ЧÀÍÆ÷¶ÁÈ¡µ½»º´æ£¬¿ª¶ËÍÆËÍÐÅÏ¢£¬²¢¹Ø±ÕÌÞ³ýÁ¬½Ó£º

Ç°¶ËÁÔÈ¡ÐÅÏ¢£¬´¦ÖõǼ£º

ɨÂëµÇ¼µÄʵÏÖ

ÁôÒ⣺±¾ Demo Ö»ÊǸöÈËѧϰ²âÊÔ£¬ËùÒÔ²¢Î´×öÌ«¶àƽ°²»úÖÆ£¡

Socket ´úÀíЧÀÍÆ÷

ʹÓà Nginx ×÷Ϊ´úÀí socke ЧÀÍÆ÷¡£¿ÉʹÓÃÓòÃû£¬Àû±ã×ö¸ºÔØƽºâ¡£±¾´Î²âÊÔÓòÃû£ºloc.websocket.net

websocker.conf

server {
    listen       80;
    server_name  loc.websocket.net;
    root   /www/websocket;
    index  index.php index.html index.htm;
    #charset koi8-r;

    access_log /dev/null;
    #access_log  /var/log/nginx/nginx.localhost.access.log  main;
    error_log  /var/log/nginx/nginx.websocket.error.log  warn;

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location / {
        proxy_pass http://php-cli:8095/;
        proxy_http_version 1.1;
        proxy_connect_timeout 4s;
        proxy_read_timeout 60s;
        proxy_send_timeout 12s;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

Socket ЧÀÍÆ÷

ʹÓà PHP ¹¹½¨µÄ socket ЧÀÍÆ÷¡£Êµ¼ÊÏîÄ¿Öдó¼Ò¿ÉÒÔ˼¿¼Ê¹ÓõÚÈý·½ÀûÓ㬲»ÂÒÐÔ¸üºÃһЩ£¡

QRServer.php

<?php

require_once dirname(dirname(__FILE__)) . '/Config.php';
require_once dirname(dirname(__FILE__)) . '/lib/RedisUtile.php';
require_once dirname(dirname(__FILE__)) . '/lib/Common.php';/**
 * ɨÂëµÇ½ЧÀͶË
 * Class QRServer
 * @author BNDong */class QRServer {    private $_sock;    private $_redis;    private $_clients = array();    /**
     * socketServer constructor.     */
    public function __construct()
    {        // É趨 timeout
        set_time_limit(0);        // ´´Á¢Ò»¸öÌ×½Ó×Ö£¨Í¨Ñ¶½Úµã£©
        $this->_sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket" . PHP_EOL);
        socket_set_option($this->_sock, SOL_SOCKET, SO_REUSEADDR, 1);        // °ó¶¨µØÖ·
        socket_bind($this->_sock, \Config::QRSERVER_HOST, \Config::QRSERVER_PROT) or die("Could not bind to socket" . PHP_EOL);        // ¼àÌýÌ×½Ó×ÖÉϵÄÁ¬½Ó
        socket_listen($this->_sock, 4) or die("Could not set up socket listener" . PHP_EOL);

        $this->_redis  = \lib\RedisUtile::getInstance();
    }    /**
     * Æô¶¯Ð§ÀÍ     */
    public function run()
    {
        $this->_clients = array();
        $this->_clients[uniqid()] = $this->_sock;        while (true){
            $changes = $this->_clients;
            $write   = NULL;
            $except  = NULL;
            socket_select($changes,  $write,  $except, NULL);            foreach ($changes as $key => $_sock) {                if($this->_sock == $_sock){ // ÍƶÏÊDz»ÊÇнÓÈëµÄ socket

                    if(($newClient = socket_accept($_sock))  === false){
                        die('failed to accept socket: '.socket_strerror($_sock)."\n");
                    }

                    $buffer   = trim(socket_read($newClient, 1024)); // ¶ÁÈ¡¿ÒÇó
                    $response = $this->handShake($buffer);
                    socket_write($newClient, $response, strlen($response)); // ·¢ËÍÏìÓ¦
                    socket_getpeername($newClient, $ip); // ÁÔÈ¡ ip µØÖ·
                    $qid = $this->getHandQid($buffer);
                    $this->log("new clinet: ". $qid);                    if ($qid) { // ÑéÖ¤¿É·ñ´æÔÚ qid
                        if (isset($this->_clients[$qid])) $this->close($qid, $this->_clients[$qid]);
                        $this->_clients[$qid] = $newClient;
                    } else {
                        $this->close($qid, $newClient);
                    }

                } else {                    // Íƶ϶þάÂë¿É·ñ¹ýÆÚ
                    if ($this->_redis->exists(\lib\Common::getQidKey($key))) {

                        $loginKey = \lib\Common::getQidLoginKey($key);                        if ($this->_redis->exists($loginKey)) { // ÍƶϻáÔ±¿É·ñɨÂë
                            $this->send($key, $this->_redis->get($loginKey));
                            $this->close($key, $_sock);
                        }

                        $res = socket_recv($_sock, $buffer,  2048, 0);                        if (false === $res) {
                            $this->close($key, $_sock);
                        } else {
                            $res && $this->log("{$key} clinet msg: " . $this->message($buffer));
                        }
                    } else {
                        $this->close($key, $this->_clients[$key]);
                    }

                }
            }
            sleep(1);
        }
    }    /**
     * ¹¹½¨ÏìÓ¦
     * @param string $buf
     * @return string     */
    private function handShake($buf){
        $buf    = substr($buf,strpos($buf,'Sec-WebSocket-Key:') + 18);
        $key    = trim(substr($buf, 0, strpos($buf,"\r\n")));
        $newKey = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
        $newMessage = "HTTP/1.1 101 Switching Protocols\r\n";
        $newMessage .= "Upgrade: websocket\r\n";
        $newMessage .= "Sec-WebSocket-Version: 13\r\n";
        $newMessage .= "Connection: Upgrade\r\n";
        $newMessage .= "Sec-WebSocket-Accept: " . $newKey . "\r\n\r\n";        return $newMessage;
    }    /**
     * ÁÔÈ¡ qid
     * @param string $buf
     * @return mixed|string     */
    private function getHandQid($buf) {
        preg_match("/^[\s\n]?GET\s+\/\?qid\=([a-z0-9]+)\s+HTTP.*/", $buf, $matches);
        $qid = isset($matches[1]) ? $matches[1] : '';        return $qid;
    }    /**
     * ±àÒë·¢ËÍÊý¾Ý
     * @param string $s
     * @return string     */
    private function frame($s) {
        $a = str_split($s, 125);        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;
    }    /**
     * ½âÎö½ÓÊÕÊý¾Ý
     * @param resource $buffer
     * @return null|string     */
    private function message($buffer){
        $masks = $data = $decoded = null;
        $len = ord($buffer[1]) & 127;        if ($len === 126)  {
            $masks = substr($buffer, 4, 4);
            $data = substr($buffer, 8);
        } else if ($len === 127)  {
            $masks = substr($buffer, 10, 4);
            $data = substr($buffer, 14);
        } else  {
            $masks = substr($buffer, 2, 4);
            $data = substr($buffer, 6);
        }        for ($index = 0; $index < strlen($data); $index++) {
            $decoded .= $data[$index] ^ $masks[$index % 4];
        }        return $decoded;
    }    /**
     * ·¢ËÍÐÂÎÅ
     * @param string $qid
     * @param string $msg     */
    private function send($qid, $msg)
    {
        $frameMsg = $this->frame($msg);
        socket_write($this->_clients[$qid], $frameMsg, strlen($frameMsg));
        $this->log("{$qid} clinet send: " . $msg);
    }    /**
     * ¹Ø±Õ socket
     * @param string $qid
     * @param resource $socket     */
    private function close($qid, $socket)
    {
        socket_close($socket);        if (array_key_exists($qid, $this->_clients)) unset($this->_clients[$qid]);
        $this->_redis->del(\lib\Common::getQidKey($qid));
        $this->_redis->del(\lib\Common::getQidLoginKey($qid));
        $this->log("{$qid} clinet close");
    }    /**
     * ÈÕÖ¾¼ÇÔØ
     * @param string $msg     */
    private function log($msg)
    {
        echo '['. date('Y-m-d H:i:s') .'] ' . $msg . "\n";
    }
}

$server = new QRServer();
$server->run();

µÇ¼ҳÃæ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ɨÂëµÇ¼ - ²âÊÔÒ³Ãæ</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="./public/css/main.css">
</head>
<body translate="no">

<p class='box'>
    <p class='box-form'>
        <p class='box-login-tab'></p>
        <p class='box-login-title'>
            <p class='i i-login'></p><h2>怬</h2>
        </p>
        <p class='box-login'>
            <p class='fieldset-body' id='login_form'>
                <button onclick="openLoginInfo();" class='b b-form i i-more' title='Mais Informa??es'></button>
                <p class='field'>
                    <label for='user'>»áÔ±ÕË»§</label>
                    <input type='text' id='user' name='user' title='Username' placeholder="ÇëÊäÈë»áÔ±ÕË»§/ÓÊÏäµØÖ·" />
                </p>
                <p class='field'>
                    <label for='pass'>»áÔ±ÃÜÂë</label>
                    <input type='password' id='pass' name='pass' title='Password' placeholder="ÇéÊäÈëÕË»§ÃÜÂë" />
                </p>
                <label class='checkbox'>
                    <input type='checkbox' value='TRUE' title='Keep me Signed in' /> ¼ÇסÎÒ                </label>
                <input type='submit' id='do_login' value='怬' title='怬' />
            </p>
        </p>
    </p>
    <p class='box-info'>
        <p><button onclick="closeLoginInfo();" class='b b-info i i-left' title='Back to Sign In'></button><h3>ɨÂëµÇ¼</h3>
        </p>
        <p class='line-wh'></p>
        <p style="position: relative;">
            <input type="hidden" id="qid" value="">
            <p id="qrcode-exp">¶þάÂëÒÑʧЧ<br>µã»÷´ÓÐÂÁÔÈ¡</p>
            <img id="qrcode" src="" />
        </p>
    </p>
</p>
<script src='./public/js/jquery.min.js'></script>
<script src='./public/js/modernizr.min.js'></script>
<script id="rendered-js">
    $(document).ready(function () {

        restQRCode();
        openLoginInfo();
        $('#qrcode-exp').click(function () {
            restQRCode();
            $(this).hide();
        });
    });    /**
     * ·­¿ª¶þάÂë     */
    function openLoginInfo() {
        $(document).ready(function () {
            $('.b-form').css("opacity", "0.01");
            $('.box-form').css("left", "-100px");
            $('.box-info').css("right", "-100px");
        });
    }    /**
     * ¹Ø±Õ¶þάÂë     */
    function closeLoginInfo() {
        $(document).ready(function () {
            $('.b-form').css("opacity", "1");
            $('.box-form').css("left", "0px");
            $('.box-info').css("right", "-5px");
        });
    }    /**
     * ˢжþάÂë     */
    var ws, wsTid = null;
    function restQRCode() {

        $.ajax({
            url: 'http://localhost/qrcode/code.php',
            type:'post',
            dataType: "json",            async: false,
            success:function (result) {
                $('#qrcode').attr('src', result.img);
                $('#qid').val(result.qid);
            }
        });        if ("WebSocket" in window) {            if (typeof ws != 'undefined'){
                ws.close();                null != wsTid && window.clearInterval(wsTid);
            }

            ws = new WebSocket("ws://loc.websocket.net?qid=" + $('#qid').val());

            ws.onopen = function() {
                console.log('websocket ÒÑÁ¬½ÓÉÏ£¡');
            };

            ws.onmessage = function(e) {                // todo: ±¾º¯Êý×öµÇ¼´¦Ö㬵ǼÍƶϣ¬´´Á¢»º´æÐÅÏ¢£¡                console.log(e.data);                var result = JSON.parse(e.data);
                console.log(result);
                alert('µÇ¼³É¹¦£º' + result.name);
            };

            ws.onclose = function() {
                console.log('websocket Á¬½ÓÒѹرգ¡');
                $('#qrcode-exp').show();                null != wsTid && window.clearInterval(wsTid);
            };            // ·¢ËÍÐÄÌø
            wsTid = window.setInterval( function () {                if (typeof ws != 'undefined') ws.send('1');
            }, 50000 );

        } else {            // todo: ²»Ö§³Å WebSocket µÄ£¬¿ÉÒÔʹÓà js ÂÖѯ´¦Öã¬ÕâÀï²»×÷¸Ã¹¦Ð§ÊµÏÖ£¡
            alert('ÄúµÄÔĶÁÆ÷²»Ö§³Å WebSocket£¡');
        }
    }</script>
</body>
</html>

µÇ¼´¦ÖÃ

²âÊÔʹÓã¬Ä£ÄâµÇ¼´¦Öã¬Î´×öƽ°²ÈÏÖ¤£¡£¡

<?php

require_once dirname(__FILE__) . '/lib/RedisUtile.php';
require_once dirname(__FILE__) . '/lib/Common.php';/**
 * -------  µÇ¼Âß¼­Ä£Äâ --------
 * Çë°´ÕÕʵ¼Ê±àдµÇ¼Âß¼­²¢´¦ÖÃƽ°²ÑéÖ¤ */$qid = $_GET['qid'];
$uid = $_GET['uid'];

$data = array();switch ($uid)
{    case '1':
        $data['uid']  = 1;
        $data['name'] = 'ÕÅÈý';        break;    case '2':
        $data['uid']  = 2;
        $data['name'] = 'ÀîËÄ';        break;
}

$data  = json_encode($data);
$redis = \lib\RedisUtile::getInstance();
$redis->setex(\lib\Common::getQidLoginKey($qid), 1800, $data);

¸ü¶àÏà¹Ø֪ʶ£¬Çë°Ý·ÃPHPÖÐÎÄÍø£¡

ÒÔÉϾÍÊÇ·ÖÏíPHPɨÂëµÇ¼µÀÀí¼°ÊµÏÖ°ì·¨µÄ¾ßÌåÄÚÈÝ£¬¸ü¶àÇë¹Ø×¢°Ù·Ö°ÙÔ´ÂëÍøÆäËüÏà¹ØÎÄÕ£¡

´òÉÍ

´òÉÍ

È¡Ïû

¸ÐлÄúµÄÖ§³Ö£¬ÎÒ»á¼ÌÐøŬÁ¦µÄ!

ɨÂëÖ§³Ö
ɨÂë´òÉÍ£¬Äã˵¶àÉپͶàÉÙ

´ò¿ªÖ§¸¶±¦É¨Ò»É¨£¬¼´¿É½øÐÐɨÂë´òÉÍŶ

°Ù·Ö°ÙÔ´ÂëÍø ½¨Òé´òÉÍ1¡«10Ôª£¬ÍÁºÀËæÒ⣬¸ÐлÄúµÄÔĶÁ£¡

¹²ÓÐ150ÈËÔĶÁ£¬ÆÚ´ýÄãµÄÆÀÂÛ£¡·¢±íÆÀÂÛ
êdzƣº ÍøÖ·£º ÑéÖ¤Â룺 µã»÷ÎÒ¸ü»»Í¼Æ¬
×îÐÂÆÀÂÛ

±¾ÎıêÇ©

¹ã¸æÔÞÖú

ÄܳöÒ»·ÖÁ¦ÊÇÒ»·Ö°É£¡

¶©ÔÄ»ñµÃ¸ü¶àÄ£°å

±¾ÎıêÇ©

¹ã¸æÔÞÖú

¶©ÔÄ»ñµÃ¸ü¶àÄ£°å