UC应用通讯失败问题排查

1、UC通讯原理php

咱们用火狐能够看到,UCENTER跟应用通讯的地址以下http://bbs.zhiyin.cn/ucenter/admin.php?m=app&a=ping&inajax=1&url=http%3A%2F%2Fapp.zhiyin.cn&ip=192.168.193.64&appid=33&random=1789609938&sid=d6c6MilHehc1GRqHPB14s6eyWNVp84nE3wbbjmf9MBnGQjsqRRnzY%2Fh2w9y1ZXMxvyeT7cSMsJRUaw
html

咱们调试的时候用火狐能够在“应用管理”菜单中右侧右键点击,而后此框架在新标签页打开,这样在火狐firebug中能够清晰看到get过来的东西,其实也就是html中看到的testlink的地址,只不过加了个随机码而已。
ajax

其实请求的是uc服务端的/control/admin/app.php的onping方法(通常状况下会进入以下红色的那段的,而不是上面那个IF),代码以下数据库

function onping() {
        $ip = getgpc('ip');
        $url = getgpc('url');
        $appid = intval(getgpc('appid'));
        $app = $_ENV['app']->get_app_by_appid($appid);
        $status = '';
        if($app['extra']['apppath'] && @include  $app['extra']['apppath'].'./api/'.$app['apifilename']) {
            $uc_note = new uc_note();
            $status = $uc_note->test($note['getdata'], $note['postdata']);
        } else {
            $this->load('note');
            $url = $_ENV['note']->get_url_code('test', '', $appid);api

            //$this->writelog('ping_url', $url);//若是须要看实际的URL为何,能够在这里写日志后而后去data/logs里面去看url,实际上是url/api/uc.php?code=XXXX,code解密后就是action跟time数组,也是后面提到的东西。
            $status = $_ENV['app']->test_api($url, $ip);
        }
        if($status == 1) {
            echo 'document.getElementById(\'status_'.$appid.'\').innerHTML = "<img src=\'images/correct.gif\' border=\'0\' class=\'statimg\' \/><span class=\'green\'>'.$this->lang['app_connent_ok'].'</span>";testlink();';
        } else {
            echo 'document.getElementById(\'status_'.$appid.'\').innerHTML = "<img src=\'images/error.gif\' border=\'0\' class=\'statimg\' \/><span class=\'red\'>'.$this->lang['app_connent_false'].'</span>";testlink();';
        }
    }数组

请求的是model/app.php的test_api方法浏览器

function test_api($url, $ip = '') {
        $this->base->load('misc');
        if(!$ip) {
            $ip = $_ENV['misc']->get_host_by_url($url);
        }

        if($ip < 0) {
            return FALSE;
        }
        return $_ENV['misc']->dfopen($url, 0, '', '', 1, $ip);
}
服务器

请求的是model/misc.php的dfopen方法,这个方法就不贴了,其实就是一个跟远程端通讯,看返回的是否是字符串1,是1就通讯成功,0就是通讯失败,通讯的url是什么呢,app

其实地址是用get_url_code方法获取的(能够在前面的ONPING方法里面看到是经过$_ENV['note']->get_url_code('test', '', $appid);获取的),在model/note里面框架

function get_url_code($operation, $getdata, $appid) {
        $app = $this->apps[$appid];
        $authkey = $app['authkey'];
        $url = $app['url'];
        $apifilename = isset($app['apifilename']) && $app['apifilename'] ? $app['apifilename'] : 'uc.php';
        $action = $this->operations[$operation][1];
        $code = urlencode($this->base->authcode("$action&".($getdata ? "$getdata&" : '')."time=".$this->base->time, 'ENCODE', $authkey));
        return $url."/api/$apifilename?code=$code";
    }

能够看出来是与在应用中填写的地址的api目录的appfilename通讯,不修改的话将是uc.php

其实如上只是叙述逻辑,真正的UC通讯失败大可能是由于数据库连接没写正确,服务器时间没有设置对,客户端没有权限连接服务端数据库,而均可以经过以下几个方式来排查错误。

因此



一、UCENTER是否支持内网通讯(能够在model/misc.php中的dfopen方法中//$this->writelog('fp', $fp);中看结果,返回资源id则表示自己跟客户端通讯成功,是客户端返回错误)

绝对支持的,咱们日常的通讯失败通常都是客户端这块写错了,所以咱们能够在客户端的api目录里面写一个uc2.php,内容为<?php echo 1;?>,同时在uc应用中将接口文件名换成uc2.php,若是能通讯成功则表示UC服务端跟客户端通讯没问题,是你的uc.php写错了,问题排查要在这里排查。若是不能通讯,则是UC服务端没法经过fsockopen访问客户端,多是域名解析问题,也多是你填写的IP问题,有IP的话服务端会优先用IP跟客户端通讯的。

二、UCENTER中填不填IP以及IP的做用

其实填写IP后的通讯速度要比填域名快,这个应用地址其实只是起个域名解析的做用的,最终依然会与客户端的这个应用的IP进行通讯,也就是api里面的uc.php通讯。若是你的应用没上线以前是能够填写个局域网的IP用于测试的,不过要保证UC的服务端能跟客户端的这个IPfsckopen,不然也是会失败的,检测方法见第一条。

三、UCENTER通讯是否须要客户端的数据库填写正确以及UC的参数填写正确(其实UC应用管理里面生成的数据库连接参数并不必定在客户端有权限连接UC的数据库服务器,这也是致使UC通讯失败的主要缘由。具体排查方式以下。)

uc.php通常会经过数据库链接的方式跟uc的数据库表通讯,UC在跟客户端通讯的时候会发送一个code参数给客户端,

$code = @$_GET['code'];
parse_str(_authcode($code, 'DECODE', UC_KEY), $get);
if(MAGIC_QUOTES_GPC) {
        $get = _stripslashes($get);
}

这个code包含了两部分的参数,一部分是time,一部分是action,都会放到$get数组里面,所以咱们在调试uc.php的时候,须要本身写相似以下代码模拟从uc发过来的数据

$timestamp = time();
$get['time']=time();//新增行
$get['action']='test';//新增行

if($timestamp - $get['time'] > 3600) {
        exit('Authracation has expiried');
 }

这样浏览器直接访问http://app.zhiyin.cn/api/uc.php就能够准确反映ucenter跟uc.php的通讯结果

四、终极杀招,服务器时间没有设置对致使通讯失败,TMD搞了我一上午。

我一步步调试最终到了model/misc.php的dfopen方法中,我在最后一行@fclose($fp);中加入一行$this->writelog('return', $return);由于misc.php中没有writelog方法,这个方法直接从model/admin.php中提取便可,而后将客户端的uc.php中加入一行

$timestamp = time();
/*$get['time']=time();
    $get['action']='test';

*/
 exit($get['time'].'|'.$timestamp.$get['action']);
 if($timestamp - $get['time'] > 3600) {
        exit('Authracation has expiried');
}

实际上是由于我看/bbs/ucenter/data/logs/中写的日志中有Authracation has expiried我才想到多是UC的服务器跟客户端的服务器不是一台服务器,两台服务器环境不一样,取到的时间不一样致使超时形成“假冒”的通讯失败,这个通讯失败是人为的访问客户端http://app.zhiyin.cn/api/uc.php发现不了的,由于你确定是给time以及action赋值了来看是不是客户端uc.php书写错误致使通讯失败。但UC服务端实际发送过程当中的时间跟客户端取到的时间不一致直接报超时。这个通讯失败我告诉你,通常人是绝对发现不了这个问题的。

相关文章
相关标签/搜索