discuz 用户整合ucenter的 fsockopen 通信问题解决

     我用的是Discuz! X3.1,是比较新的版本,我的服务器环境是FreeBSD 8.2-RELEASE-p9;  web服务器为apache;mysql数据库和web服务器在同一台服务器上;安装discuz过程中没有任何错误和警告;安装好之后访问OK,但是和我的网站通信过程中出现用户不能同步的问题,部署过程和排错过程如下:

 整合过程:

1,将安装好的论坛下的uc_client,config,data 等复制到自己网站主目录

2,登陆论坛,在管理中心打开ucenter用户管理中心,点开应用程序  添加自己的网站到应用列表中,应用类型选择为其他 ,应用的主URL填写自己网站的主地址;

3,如果通信不成功,最好写上应用IP地址,如果网站和论坛在同一个服务器上,那写上127.0.0.1即可;因为当我们的请求送达服务器时,其实用户同步是服务器和服务器之间的通信;

按照以上步骤操作完成后,网站和论坛的通信已经成功了;下边实现注册登录免激活操作,将自己网站的用户名密码邮箱信息发送到bbs,实现一键跳转登陆;

下边是接收用户信息,实现注册,登陆免激活的代码,

我们自己的网站加一个链接,点击后的 URL为 http://192.168.0.5:8090/login?username=hello&password=123&email=test@qq.com ,下边的loginAction负责处理

     public function loginAction(){            
            $request=$this->getRequest();
            $username=$request->get("username");
            $userpass=$request->get('password');
            $email=$request->get('email');
            define('IN_COMSENZ',"");
            $domain = "http://192.168.0.5:8090/";
            include 'config/config_global.php';
            include 'config/config_ucenter.php';
            include 'uc_client/client.php';         
            $uid = uc_user_register($username, $userpass, $email);          
            if ($uid <= 0) {
                    if ($uid == -1) {
                        echo '用户名不合法';
                    } elseif ($uid == -2) {
                        echo '包含要允许注册的词语';
                    } elseif ($uid == -3) {      
                        //echo '正在登入系统...';
                    } elseif ($uid == -4) {
                        echo 'Email 格式有误';
                    } elseif ($uid == -5) {
                        echo 'Email 不允许注册';
                    } elseif ($uid == -6) {
                        echo '该 Email 已经被注册';
                    } else {
                        echo '未定义';
                    }
            }
            $ucsynlogin="error";
            $url='<script>location.href='.$domain.'bbs/forum.php</script>';
            list($uid, $username, $userpass, $email) = uc_user_login($username, $userpass);
               
                if ($uid > 0) {                  
                     $ucsynlogin = uc_user_synlogin($uid);       //如果成功,此处会返回一段js,输出到页面执行后,本地也就写入了cookie,跳转时候也就登陆成功了   
                     echo "正在跳转...";
                     $url="<script>location.href='http://192.168.0.5:8090/bbs/forum.php';</script>";                     
                     echo $ucsynlogin;
                     echo $url;                  
                } elseif ($uid == -1) {
                    echo '用户不存在,或者被删除';
                } elseif ($uid == -2) {
                    echo '密码错';
                } else {
                    echo '未定义';
                }           
           // return $this->render("AcmeMspBundle:BBS:login.html.twig",array('url'=>$url,'uid'=>$uid,'js'=>$ucsynlogin));
        }

如果发现ucenter 里边已经插入数据,而common_member却没有数据,那是因为注册之后没有激活,所以也没有办法实现跳转登陆,具体解决办法如下:

找到bbs目录下的api里边的uc.php,用一下实现方式替换synlogin函数;具体如下:

function synlogin($get, $post){   
    global $_G;
    if(!API_SYNLOGIN) 
    return API_RETURN_FORBIDDEN;
    header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
    $cookietime = 31536000;
    $uid = intval($get['uid']);
    $query = DB::query("SELECT uid, username, password FROM ".DB::table('common_member')." WHERE uid='$uid'");
    if($member = DB::fetch($query)) 
    dsetcookie('auth', authcode("$member[password]\t$member[uid]", 'ENCODE'), $cookietime);
    $username = $get['username']; 
    $password = md5(time().rand(100000, 999999));
    $email = $get['email'];
    $ip = $_SERVER['REMOTE_ADDR'];
    $time = time(); 
    $userdata = array(
    'uid' => $uid,
    'username' => $username,
    'password' => $password,
    'email' => $email,
    'adminid' => 0,
    'groupid' => 10,
    'regdate' => $time,
    'credits' => 0,
    'timeoffset' => 9999
    );
    DB::insert('common_member', $userdata);
    $status_data = array(
    'uid' => $uid,
    'regip' => $ip,
    'lastip' => $ip,
    'lastvisit' => $time,
    'lastactivity' => $time,
    'lastpost' => 0,
    'lastsendmail' => 0,
    );
    DB::insert('common_member_status', $status_data);
    DB::insert('common_member_profile', array('uid' => $uid));
    DB::insert('common_member_field_forum', array('uid' => $uid));
    DB::insert('common_member_field_home', array('uid' => $uid));
    DB::insert('common_member_count', array('uid' => $uid)); 
    $query = DB::query("SELECT uid, username, password FROM ".DB::table('common_member')." WHERE uid='$uid'");
    if ($member = DB::fetch($query)) {          
                dsetcookie('auth', authcode("$member[password]\t$member[uid]", 'ENCODE'), $cookietime);
            }
}
一般正常情况下,通过以上方式就可以实现注册自动登陆一体完成;如果还是无法实现登陆修改如下代码: 自己网站的uc_client 下的client.php

function uc_user_synlogin($uid) {
	$uid = intval($uid);
	if(@include UC_ROOT.'./data/cache/apps.php') {
		if(count($_CACHE['apps']) > 1) {
			$return = uc_api_post('user', 'synlogin', array('uid'=>$uid));
		} else {
			$return = '';
                        //不管执行if还是else  强制执行将else里边的 $return=''; 改为下边的;有时候确实因为配置问题导致不能执行uc_api_post函数
                        $return = uc_api_post('user', 'synlogin', array('uid'=>$uid));
		}
	}
	return $return;
}
如果通过以上方式还是存在问题,首先应该一步异步排除php配置allow_url_open = On,扩展是否打开sockets.so,linux防火墙端口是否添加例外,也可以字节写一段php的socket程序,测试一下服务器的环境是否已经支持php的socket.也顺便检查一下以下代码:

在我们网站的uc_client 下的client.php  ,这个文件负责和论坛下的uc_server通信,来实现一些列同步操作的;他主要的方式也是通过fsockopen 来模拟http协议实现数据传输的;可以查看client.php 里边的一下函数,稍作适当修改(前提是服务器已经支持socket)

//模拟http请求的socket的实现
function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) {
	$return = '';
	$matches = parse_url($url);
	!isset($matches['host']) && $matches['host'] = '';
	!isset($matches['path']) && $matches['path'] = '';
	!isset($matches['query']) && $matches['query'] = '';
	!isset($matches['port']) && $matches['port'] = '';
	$host = $matches['host'];
	$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
	$port = !empty($matches['port']) ? $matches['port'] : 80;
	if($post) {
		$out = "POST $path HTTP/1.0\r\n";
		$out .= "Accept: */*\r\n";
		//$out .= "Referer: $boardurl\r\n";
		$out .= "Accept-Language: zh-cn\r\n";
		$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
		$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
		$out .= "Host: $host\r\n";
		$out .= 'Content-Length: '.strlen($post)."\r\n";
		$out .= "Connection: Close\r\n";
		$out .= "Cache-Control: no-cache\r\n";
		$out .= "Cookie: $cookie\r\n\r\n";
		$out .= $post;
	} else {
		$out = "GET $path HTTP/1.0\r\n";
		$out .= "Accept: */*\r\n";
		//$out .= "Referer: $boardurl\r\n";
		$out .= "Accept-Language: zh-cn\r\n";
		$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
		$out .= "Host: $host\r\n";
		$out .= "Connection: Close\r\n";
		$out .= "Cookie: $cookie\r\n\r\n";
	}
        //可以放开下边一行注释试试
        //$host='127.0.0.1'; $ip='127.0.0.1';
	if(function_exists('fsockopen')) {
		$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
                 //如果$fp 操作超时 errno 600  ,应该是服务器IP的问题,如果bbs的web服务器和自己网站的web服务器在同一台服务器,建议使用127.0.0.1 ,让过不必要的阻挡;
                
	} elseif (function_exists('pfsockopen')) {
		$fp = @pfsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
	} else {
		$fp = false;
	}
                //在此处调试$fp的值 ,尽量使用print_r($fp);
	if(!$fp) {
                //有时候会再此处返回 socket却是为null的值
		return '';
	} else {
		stream_set_blocking($fp, $block);
		stream_set_timeout($fp, $timeout);
		@fwrite($fp, $out);
		$status = stream_get_meta_data($fp);
		if(!$status['timed_out']) {
			while (!feof($fp)) {
				if(($header = @fgets($fp)) && ($header == "\r\n" ||  $header == "\n")) {
					break;
				}
			}

			$stop = false;
			while(!feof($fp) && !$stop) {
				$data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
				$return .= $data;
				if($limit) {
					$limit -= strlen($data);
					$stop = $limit <= 0;
				}
			}
		}
		@fclose($fp);
		return $return;
	}
}

通过修改以上fsockopen函数的 IP直接为127.0.0.1 ,也可以实现通信成功!,(前提是网站和bbs同在一个服务器)

如果ucenter插入用户数据成功,discuz插入用户数据不成功,大部分情况下是以上函数socket通信失败造成的,可以在此处盘查;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值