uc_client是如何与UCenter进行通信的
2012-08-25 00:10
537 查看
以用户登录为例介绍,其它注销,改密码,消息,头像,好友均类同。
从用户xxx在某一应用程序的login.php,输入用户名,密码讲起。先用uc_user_login函数到uc_server验证此用户和密码,如正确,则写入session,写入cookies,并更新应用程序会员表中的登录ip,登录时间。用户感觉不到这个过程。
然后通过uc_user_synlogin通知uc_server 用户xxx登录成功,这个过程可能使用ajax,用户感觉不到通知过程。
uc_server收到这个消息后,马上命令手下,把xxx登录的消息,像令牌环一样,发给所有愿意接收(后台中那个是否开启同步登录)这个消息的其它应用程序。其实就是带参数访问一下各应用程序的uc.php,用户感觉不到这个过程。
各应用程序靠api下的uc.php来接收uc_server发来的消息,并对uc_server言听计从,让干什么就干什么。现在,收到让xxx用户在你的程序中登录的命令,马上执行。并写本应用程序的session,并且使用p3p,写入相同域或不同域的cookies. 用户感觉不到这个过程。
最后所有和uc整合的程序,xxx均登录成功。用户从www.test.com/bbs登录后, 跳到www.test.com/news同样显示登录。因为bbs 和news系统在后台均已登录。
应用程序与uc server的会话结束。
得益于uc设计的精巧过程,整个过程,用户完全感觉不到ucenter的存在。这是整合程序历史上的创新。
以下为Supesite的uc_client和ucenter登录通信过程的一个例子:
1、登录入口index.php?action=login
提交登录action:batch.login.php?action=login
2、登录处理地址batch.login.php?action=login
如果登录成功,则查本地用户信息。如果有更新本地信息,如果没有插入新的用户数据保持与ucenter进行同步。
然后同步其他子系统登录信息:
下面是一些程序代码与注释:
远程同步登录子系统操作之后:
从用户xxx在某一应用程序的login.php,输入用户名,密码讲起。先用uc_user_login函数到uc_server验证此用户和密码,如正确,则写入session,写入cookies,并更新应用程序会员表中的登录ip,登录时间。用户感觉不到这个过程。
然后通过uc_user_synlogin通知uc_server 用户xxx登录成功,这个过程可能使用ajax,用户感觉不到通知过程。
uc_server收到这个消息后,马上命令手下,把xxx登录的消息,像令牌环一样,发给所有愿意接收(后台中那个是否开启同步登录)这个消息的其它应用程序。其实就是带参数访问一下各应用程序的uc.php,用户感觉不到这个过程。
各应用程序靠api下的uc.php来接收uc_server发来的消息,并对uc_server言听计从,让干什么就干什么。现在,收到让xxx用户在你的程序中登录的命令,马上执行。并写本应用程序的session,并且使用p3p,写入相同域或不同域的cookies. 用户感觉不到这个过程。
最后所有和uc整合的程序,xxx均登录成功。用户从www.test.com/bbs登录后, 跳到www.test.com/news同样显示登录。因为bbs 和news系统在后台均已登录。
应用程序与uc server的会话结束。
得益于uc设计的精巧过程,整个过程,用户完全感觉不到ucenter的存在。这是整合程序历史上的创新。
以下为Supesite的uc_client和ucenter登录通信过程的一个例子:
1、登录入口index.php?action=login
//系统频道 if($_SGET['action'] != 'index') { if(empty($channels['menus'][$_SGET['action']]['upnameid']) && $channels['menus'][$_SGET['action']]['upnameid'] != 'news') { $scriptfile = S_ROOT.'./'.$_SGET['action'].'.php'; } else { $scriptfile = S_ROOT.'./news.php'; } //echo $scriptfile; if(file_exists($scriptfile)) { include_once($scriptfile); exit(); } }
提交登录action:batch.login.php?action=login
2、登录处理地址batch.login.php?action=login
include_once(S_ROOT.'./uc_client/client.php'); // 登录操作及其中涉及到的一些函数: $password = $_POST['password']; $username = $_POST['username']; // 去ucenter进行远程登录验证 $ucresult = uc_user_login($username, $password, $loginfield == 'uid');
如果登录成功,则查本地用户信息。如果有更新本地信息,如果没有插入新的用户数据保持与ucenter进行同步。
然后同步其他子系统登录信息:
$msg = $lang['login_succeed'].uc_user_synlogin($members['uid']); function uc_user_synlogin($uid) { $uid = intval($uid); $return = uc_api_post('user', 'synlogin', array('uid'=>$uid)); return $return; }
下面是一些程序代码与注释:
/** * dfopen 方式取指定的模块和动作的数据 * * @param string $module 请求的模块 * @param string $action 请求的动作 * @param array $arg 参数(会加密的方式传送) * @return string */ function uc_api_post($module, $action, $arg = array()) { $s = $sep = ''; foreach($arg as $k => $v) { $k = urlencode($k); if(is_array($v)) { $s2 = $sep2 = ''; foreach($v as $k2 => $v2) { $k2 = urlencode($k2); $s2 .= "$sep2{$k}[$k2]=".urlencode(uc_stripslashes($v2)); $sep2 = '&'; } $s .= $sep.$s2; } else { $s .= "$sep$k=".urlencode(uc_stripslashes($v)); } $sep = '&'; } $postdata = uc_api_requestdata($module, $action, $s); return uc_fopen2(UC_API.'/index.php', 500000, $postdata, '', TRUE, UC_IP, 20); } /** * 构造发送给用户中心的请求数据 * * @param string $module 请求的模块 * @param string $action 请求的动作 * @param string $arg 参数(会加密的方式传送) * @param string $extra 附加参数(传送时不加密) * @return string */ function uc_api_requestdata($module, $action, $arg='', $extra='') { $input = uc_api_input($arg); $post = "m=$module&a=$action&inajax=2&release=".UC_CLIENT_RELEASE."&input=$input&appid=".UC_APPID.$extra; return $post; } function uc_api_url($module, $action, $arg='', $extra='') { $url = UC_API.'/index.php?'.uc_api_requestdata($module, $action, $arg, $extra); return $url; } function uc_api_input($data) { $s = urlencode(uc_authcode($data.'&agent='.md5($_SERVER['HTTP_USER_AGENT'])."&time=".time(), 'ENCODE', UC_KEY)); return $s; } /** * 远程打开URL * @param string $url 打开的url, 如 http://www.baidu.com/123.htm * @param int $limit 取返回的数据的长度 * @param string $post 要发送的 POST 数据,如uid=1&password=1234 * @param string $cookie 要模拟的 COOKIE 数据,如uid=123&auth=a2323sd2323 * @param bool $bysocket TRUE/FALSE 是否通过SOCKET打开 * @param string $ip IP地址 * @param int $timeout 连接超时时间 * @param bool $block 是否为阻塞模式 * @return 取到的字符串 */ function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE) { $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1; if($__times__ > 2) { return ''; } $url .= (strpos($url, '?') === FALSE ? '?' : '&')."__times__=$__times__"; return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block); } 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"; } $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout); if(!$fp) { return '';//note $errstr : $errno \r\n } 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; } }
远程同步登录子系统操作之后:
//显示信息 function showmessage($message, $url_forward='', $second=3, $vars=array()) { global $_SGLOBAL, $_SCONFIG, $_SC, $channels; if(empty($_SGLOBAL['inajax']) && $url_forward && empty($second)) { //直接301跳转 obclean(); header("HTTP/1.1 301 Moved Permanently"); header("Location: $url_forward"); } else { if(!defined('IN_SUPESITE_ADMINCP')) { $tpl_file = 'showmessage'; $fullpath = 0; include_once(S_ROOT.'./language/message.lang.php'); if(!empty($mlang[$message])) $message = $mlang[$message]; } else { $tpl_file = 'admin/tpl/showmessage.htm'; $fullpath = 1; include_once(S_ROOT.'./language/admincp_message.lang.php'); if(!empty($amlang[$message])) $message = $amlang[$message]; } if(isset($_SGLOBAL['mlang'][$message])) $message = $_SGLOBAL['mlang'][$message]; foreach ($vars as $key => $val) { $message = str_replace('{'.$key.'}', $val, $message); } //显示 obclean(); if(!empty($url_forward)) { $second = $second * 1000; $message .= "<script>setTimeout(\"window.location.href ='$url_forward';\", $second);</script><ajaxok>"; } include template($tpl_file, $fullpath); ob_out(); } exit(); }
相关文章推荐
- uc_client是如何与UCenter进行通信的
- uc_client是如何与UCenter进行通信的
- Uc_client与ucenter通信原理
- [原创]WCF后续之旅(1): WCF是如何通过Binding进行通信的
- QQ通信原理及QQ是如何穿透内网进行通信的
- 【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信
- 如何使用 volatile, synchronized, final 进行线程间通信
- centos7下安装docker(12.4容器如何与外部进行通信)
- 单片机是如何与电脑进行通信的,电子工程师必知内容(转)
- windows下无MySQL Command Line Client如何进行mysql命令行界面编辑
- p2p软件如何穿透内网进行通信
- 转 winfrom如何通过http来进行通信,并且通过传递json格式的数据可接受json格式的数据
- 如何进行多平台部署Client和Server详细讲解
- dede与discuz通过ucenter通信uc_server
- 进程通信中如何进行值得传递?
- 基于非阻塞socket的多线程服务器的实现------一个服务器如何与多个客户端进行通信?
- 如何使用 volatile, synchronized, final 进行线程间通信
- p2p软件如何穿透内网进行通信
- 如何配置 NETGEAR *** Client 软件与 FVX538/FVS338 V2.0 进行 *** 连接
- Hadoop中NameNode、DataNode和Client三者之间的通信方式是什么?怎样进行合作?