• web-msg-sender的https支持改造


    用的是nginx代理转发443到2120端口实现,官方说workman原生支持,没有实现(现象是 访问 htttps://域名:2120/ 超时,不知道是服务器问题还是什么)

    后转为用nginx代理转发实现

    1、假设用https://socket.test.com 作为socket连接的地址. https://www.test.com还是网站本身,实现共存,不影响主站访问

    1、nginx的 网站.conf,注意红色部分。2121那个转发不是必须的,因为是服务端curl请求,可以直接请求ip地址带端口

    server
        {
        listen 443;
        server_name *.test.com test.com;
    
    
        set $flag 0;
    if ($host != 'www.test.com') {
            set $flag "${flag}1";
            
    }
     
    if ($host = 'socket.test.com'){
            set $flag "${flag}1";
    }
     
    if ($flag = "01"){
            rewrite ^/(.*)$ http://www.test.com/$1 permanent;
    }
        #if ($host != 'www.test.com' ) {
            
       # }
        ssl on;
        ssl_certificate   cert/cert-1542176077391__.test.com.crt;
        ssl_certificate_key  cert/cert-1542176077391__.test.com.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
    
            index index.html index.htm index.php default.html default.htm default.php;
            root  /home/wwwroot/test;
            error_page   404   /404.html;
    
    location /push.api
      {
        proxy_pass http://127.0.0.1:2121;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Real-IP $remote_addr;
      }
    location /socket.io
      {
        proxy_pass http://127.0.0.1:2120;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Real-IP $remote_addr;
      }
    
    
            location /{
            if (!-e $request_filename) {
                rewrite ^/(.+.(html|xml|json|htm|php|jsp|asp|shtml))$ /index.php?$1 last; 
            }  
            # Deny access to PHP files in specific directory
            #location ~ /(wp-content|uploads|wp-includes|images)/.*.php$ { deny all; }
    
                include enable-php5.2.conf;
            }
    
    
            location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
            {
                expires      30d;
            }
    
            location ~ .*.(js|css)?$
            {
                expires      12h;
            }
    
            location ~ /.well-known {
                allow all;
            }
    
            location ~ /.
            {
                deny all;
            }
    
            #access_log  /home/wwwlogs/test.com.log;
        }

    2、服务端socket.io.php,无需更改。还是用端口2120,不用开启ssl

    <?php
    use WorkermanWorker;
    use WorkermanWebServer;
    use WorkermanLibTimer;
    use PHPSocketIOSocketIO;
    
    include __DIR__ . '/vendor/autoload.php';
    
    // 全局数组保存uid在线数据
    $uidConnectionMap = array();
    // 记录最后一次广播的在线用户数
    $last_online_count = 0;
    // 记录最后一次广播的在线页面数
    $last_online_page_count = 0;
    
    // PHPSocketIO服务
    $sender_io = new SocketIO(2120);
    // 客户端发起连接事件时,设置连接socket的各种事件回调
    $sender_io->on('connection', function($socket){
    
        file_put_contents('/home/wwwroot/test/home/socketioserver.txt',date('Y-m-d H:i:s')."
     connection:uid:".$uid."
    =======
    ",FILE_APPEND);
    
        /**/
       // error_reporting(E_ALL ^ E_NOTICE);
        //$root_dir = realpath(dirname(__FILE__).'/../');
    
        //require_once($root_dir."/config/config.php");
    /*
        require_once(APP_DIR.'/base/kernel.php');
        @require_once(APP_DIR.'/base/defined.php');
    
        if(!kernel::register_autoload()){
            require_once(APP_DIR.'/base/autoload.php');
        }*/
        /**/
    
        // 当客户端发来登录事件时触发
        $socket->on('login', function ($uid)use($socket){
            file_put_contents('/home/wwwroot/test/home/socketioserver.txt',date('Y-m-d H:i:s')."
     login:uid:".$uid."
    =======
    ",FILE_APPEND);
    
            global $uidConnectionMap, $last_online_count, $last_online_page_count;
            // 已经登录过了
            if(isset($socket->uid)){
                return;
            }
            // 更新对应uid的在线数据
            $uid = (string)$uid;
            if(!isset($uidConnectionMap[$uid]))
            {
                $uidConnectionMap[$uid] = 0;
            }
            // 这个uid有++$uidConnectionMap[$uid]个socket连接
            ++$uidConnectionMap[$uid];
    
      /*       $dbs= kernel::database();
            $dbs->exec('update sdb_b2c_online_users set online="'.serialize($uidConnectionMap).'"');*/
            //file_put_contents(HOME_DIR.'/chat/OnlineUsersCache.txt',serialize($uidConnectionMap));
            //app::get('b2c')->setConf('chat.online_users',$uidConnectionMap);
    
            // 将这个连接加入到uid分组,方便针对uid推送数据
            $socket->join($uid);
            $socket->uid = $uid;
            // 更新这个socket对应页面的在线数据
            $socket->emit('update_online_count',count($uidConnectionMap));
        });
        
        // 当客户端断开连接是触发(一般是关闭网页或者跳转刷新导致)
        $socket->on('disconnect', function () use($socket) {
    
            file_put_contents('/home/wwwroot/test/home/socketioserver.txt',date('Y-m-d H:i:s')."
     disconnect:uid:".$socket->uid."
    =======
    ",FILE_APPEND);
    
    
            if(!isset($socket->uid))
            {
                 return;
            }
            global $uidConnectionMap, $sender_io;
            // 将uid的在线socket数减一
            if(--$uidConnectionMap[$socket->uid] <= 0)
            {
                unset($uidConnectionMap[$socket->uid]);
            }
           // file_put_contents(HOME_DIR.'/chat/OnlineUsersCache.txt',serialize($uidConnectionMap));
    
        });
    });
    
    // 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据
    $sender_io->on('workerStart', function(){
        // 监听一个http端口
        $inner_http_worker = new Worker('http://0.0.0.0:2121');
        // 当http客户端发来数据时触发
        $inner_http_worker->onMessage = function($http_connection, $data){
            $_POST = $_POST ? $_POST : $_GET;
    
    
            if($_POST['appkey']!='fads'){
               // return $http_connection->send('fail');
            }
    
            // 推送数据的url格式 type=publish&to=uid&content=xxxx
            switch(@$_POST['type']){
                //聊天
                  case 'publish':
                    global $sender_io;
                    $to = @$_POST['to'];
                    $_POST['content'] = (@$_POST['content']);
                    // 有指定uid则向uid所在socket组发送数据
                    if($to){
                        $sender_io->to($to)->emit('new_msg', $_POST['content']);
                    // 否则向所有uid推送数据
                    }else{
                        $sender_io->emit('new_msg', @$_POST['content']);
                    }
                    // http接口返回ok
                    return $http_connection->send('ok');
    
                    break;
    
    
                //新的拍卖出价时
                  case 'new_auction_price':
                    global $sender_io;
                    $to = @$_POST['to'];
                    $_POST['content'] = (@$_POST['content']);
                    // 有指定uid则向uid所在socket组发送数据
                    if($to){
                        $sender_io->to($to)->emit('new_auction', $_POST['content']);
                        // 否则向所有uid推送数据
                    }else{
                        $sender_io->emit('new_auction_price', @$_POST['content']);
                    }
                    return $http_connection->send('ok');
    
                    break;
    
                    //创建拍卖
                    case 'create_auction':
                    global $sender_io;
                    $to = @$_POST['to'];
                    // 有指定uid则向uid所在socket组发送数据
                    if($to){
                        $sender_io->to($to)->emit('create_auction', $_POST['content']);
                        // 否则向所有uid推送数据
                    }else{
                        $sender_io->emit('create_auction', @$_POST['content']);
                    }
                    return $http_connection->send('ok');
                    break;
    
    
                    //延迟
                    case 'delay_auction':
                    global $sender_io;
                    $to = @$_POST['to'];
                    // 有指定uid则向uid所在socket组发送数据
                    if($to){
                        $sender_io->to($to)->emit('delay_auction', $_POST['content']);
                        // 否则向所有uid推送数据
                    }else{
                        $sender_io->emit('delay_auction', @$_POST['content']);
                    }
                    return $http_connection->send('ok');
                    break;
    
                     //流拍
                    case 'cancel_auction':
                    global $sender_io;
                    $to = @$_POST['to'];
                    // 有指定uid则向uid所在socket组发送数据
                    if($to){
                        $sender_io->to($to)->emit('cancel_auction', $_POST['content']);
                        // 否则向所有uid推送数据
                    }else{
                        $sender_io->emit('cancel_auction', @$_POST['content']);
                    }
                    return $http_connection->send('ok');
                    break;
    
                  //开始今日拍卖时+切换到下一个拍卖时+结束当日拍卖到下一个拍卖时
                  case 'change_domain_item':
                    global $sender_io;
                    $to = @$_POST['to'];
                    // 有指定uid则向uid所在socket组发送数据
                    if($to){
                        $sender_io->to($to)->emit('change_domain_item', $_POST['content']);
                        // 否则向所有uid推送数据
                    }else{
                        $sender_io->emit('change_domain_item', @$_POST['content']);
                    }
                    return $http_connection->send('ok');
    
    
            }
            return $http_connection->send('fail');
        };
        // 执行监听
        $inner_http_worker->listen();
    
    
    
    
        // 一个定时器,定时向所有uid推送当前uid在线数及在线页面数
        Timer::add(1, function(){
            global $uidConnectionMap, $sender_io, $last_online_count, $last_online_page_count;
            $online_count_now = count($uidConnectionMap);
            $online_page_count_now = array_sum($uidConnectionMap);
            // 只有在客户端在线数变化了才广播,减少不必要的客户端通讯
            if($last_online_count != $online_count_now || $last_online_page_count != $online_page_count_now)
            {
                $sender_io->emit('update_online_count', $online_count_now);
                $last_online_count = $online_count_now;
                $last_online_page_count = $online_page_count_now;
            }
        });
    });
    
    if(!defined('GLOBAL_START'))
    {
        Worker::runAll();
    }

    3、客户端js.最大的坑就是这里。原先以为io('地址'),是要填完整的,比如下面

    <script src='https://socket.test.com/web-msg-sender-master/socket.io-client/socket.io.js?v=123123'></script>
    <script>
    $(document).ready(function () {
    // 创建WebSocket 对象
    var socket = io("https://socket.test.com/socket.io",{debug:true});
    /*
    * 2019-08-24 11:27:35
    connection:uid:
    =======
    2019-08-24 11:28:04
    disconnect:uid:
    *
    * */


    //var socket = io("http://118.190.21.61:2120",{debug:true});
    /*
    * 2019-08-24 11:26:08
    connection:uid:
    =======
    2019-08-24 11:26:08
    login:uid:1566617168000
    =======
    2019-08-24 11:26:35
    disconnect:uid:1566617168000
    =======
    * */

    //连接成功时,触发事件
    // 连接后登录
    console.log('socket',socket);
    socket.on('connect', function(){
    socket.emit('login', uid);
    });
    // 后端推送来消息时
    socket.on('new_msg', function(msg){
    $('#content').html('收到消息:'+msg);
    $('.notification.sticky').notify();
    });
    // 后端推送来在线数据时
    socket.on('update_online_count', function(online_stat){
    $('#online_box').html(online_stat);
    });


    })
    </script>

    后来发现怎么也连不上socket服务,on事件监听完全失效。

    后来看了 lib/manager.js里源码才知道,系统会自动补全socket.io,所以初始化时io里变量只需填写域名即可,正确如下。注意红色加粗部分

    <script src='https://socket.test.com/web-msg-sender-master/socket.io-client/socket.io.js?v=123123'></script>
    <script>
    $(document).ready(function () {
                // 创建WebSocket 对象
        var socket = io("https://socket.test.com",{debug:true});
        /*
        * 2019-08-24 11:27:35
         connection:uid:
         =======
         2019-08-24 11:28:04
         disconnect:uid:
        *
        * */
    
    
        //var socket = io("http://118.190.21.61:2120",{debug:true});
        /*
        * 2019-08-24 11:26:08
         connection:uid:
         =======
         2019-08-24 11:26:08
         login:uid:1566617168000
         =======
         2019-08-24 11:26:35
         disconnect:uid:1566617168000
         =======
        * */
    
        //连接成功时,触发事件
        // 连接后登录
        console.log('socket',socket);
        socket.on('connect', function(){
            socket.emit('login', uid);
        });
        // 后端推送来消息时
        socket.on('new_msg', function(msg){
            $('#content').html('收到消息:'+msg);
            $('.notification.sticky').notify();
        });
        // 后端推送来在线数据时
        socket.on('update_online_count', function(online_stat){
            $('#online_box').html(online_stat);
        });
          
       
     })
      </script> 
  • 相关阅读:
    Android成长之路-LayoutInflater和inflate的用法
    Android成长之路-实现简单动画
    Android成长之路-编码实现软件界面
    Android成长之路-手势库的创建
    Android成长之路-手势识别的实现
    Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面
    android中文字中间有超链接的实现方法
    Arduino可穿戴教程ArduinoIDE新建编辑源文件
    FMDB使用SQLite事务Save Point
    FMDB使用Cached Statement功能
  • 原文地址:https://www.cnblogs.com/showker/p/11404170.html
Copyright © 2020-2023  润新知