今天,我们继续IM微信即时通讯案例,主要实现了登陆、加载通讯录功能,初步了解了workman的安装和服务器和客户端数据的基本交互。
一、登陆功能
首先account.php页面是欢迎界面,点击登陆页面实现跳转login.php页面,用到了js。
<!DOCTYPE html> <html> <head> <title>微信IM登录</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css"> <style type="text/css"> body{background: url('/static/image/background.jpg');background-repeat: no-repeat;background-size: cover;background-position: center 0px;} .account{position: absolute;bottom: 20px;width: 100%} .account button{width: 7rem;height: 2.3rem;border:none;border-radius: 4px;} .account .login{float: left;} .account .reg{float: right;background: rgb(5,189,5);color: #fff;} </style> </head> <body> <div class="layui-container account"> <button class="login" onclick="login()">登录</button> <button class="reg">注册</button> </div> </body> </html> <script type="text/javascript"> function login () { window.location.href = 'login.php'; } </script>
点击 "运行实例" 按钮查看在线实例
login.php是登陆页面,主要功能就是在前端通过js实现基本的账号密码完整性以及规则的验证,其次就是将表单的数据通过ajax方式同后台验证页面dologin.php产生数据交互;
<!DOCTYPE html> <html> <head> <title>登录</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" charset="UTF-8"> <link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css"> <script type="text/javascript" src="/static/layui/layui.js"></script> <style type="text/css"> .cancel{margin-top: 1rem;font-size: 1.1rem;} .cancel a{color: green;} .title{text-align: center;font-size: 1.3rem;color: #666;margin: 2rem;} .other-account{color: #666;font-size: 0.5rem;text-align: center;margin-top: 1rem;} </style> </head> <body> <!--取消--> <div class="cancel layui-container"><a href="javascript:;" onclick="cancels()">取消</a></div> <div class="title">使用手机号登录</div> <div class="layui-container layui-form layui-form-pane"> <div class="layui-form-item"> <label class="layui-form-label">国家/地区</label> <div class="layui-input-block"> <select> <option>中国</option> </select> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">+86</label> <div class="layui-input-block"> <input type="number" class="layui-input" name="phone" maxlength="11" placeholder="请填写手机号码"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">密码</label> <div class="layui-input-block"> <input type="password" class="layui-input" name="pwd" placeholder="请填写密码"> </div> </div> <button class="layui-btn layui-btn-fluid" style="background: rgb(5,189,5);" onclick="login()">登录</button> <!--其他登录方式--> <div class="other-account">通过短信验证码登录</div> </div> </body> </html> <script type="text/javascript"> //取消登陆 function cancels () { window.location.href = 'account.php'; } //引入layui的form组件 在layui下引入jqurey layui.use(['layer', 'form'], function(){ $ = layui.jquery; }); //登陆 function login() { var telephone = $('input[name="phone"]').val(); var password = $('input[name="pwd"]').val(); var isok = checkusername(telephone, password); // console.log(isok); if (isok) { //提交数据 $.post('/service/dologin.php', {username:telephone, password:password}, function(date){ if (date.code > 0) { layer.msg(date.msg, {icon:2}); } else { layer.msg(date.msg, {icon:1}); setTimeout(function () { window.location.href = '/index.php'; }, 1000); } }, 'json'); } } //校验 function checkusername(phone, pwd) { // console.log(phone.length); if (phone.length < 11) { layer.msg('手机号输入不正确', {icon:2}); return false; } if (pwd == '') { layer.msg('请输入密码', {icon:2}); return false; } return true; } </script>
点击 "运行实例" 按钮查看在线实例
后台验证页面dologin.php,这里要加载三个类页面common.php,Db.php,AES.php,来实现功能。
要先把ajax方式post过来的数据存在变量里,这里引用了common.php里的post方法主要是对post过来的数据进行验证加工
<?php function post($field='') { if (!$field) { return $_POST; } if (!isset($_POST[$field])) { return false; } return $_POST[$field]; // echo $_POST[$field]; }
点击 "运行实例" 按钮查看在线实例
然后是对数据进行验证
//post过来的数据存入变量 $phone = trim(post('username')); $pwd = trim(post('password')); //print_r($_POST); //校验 if (strlen($phone) < 11) { exit(json_encode(array('code'=>1, 'msg'=>'手机号不正确'))); } if ($pwd == '') { exit(json_encode(array('code'=>1, 'msg'=>'密码不能为空'))); }
点击 "运行实例" 按钮查看在线实例
查询数据库进行数据比对,对用户不存在和密码错误进行处理
//到数据库查询数据 $db = new Db(); $user = $db->table('member')->where(array('phone'=>$phone))->item(); if (!$user) { exit(json_encode(array('code'=>1, 'msg'=>'该用户不存在'))); } if ($user['password'] != md5($user['phone'].$pwd)) { exit(json_encode(array('code'=>1, 'msg'=>'密码错误'))); }
点击 "运行实例" 按钮查看在线实例
账号密码验证一致通过后,对数据加密存在cookie里;
二、查询表,加载出通讯录
取出cookie中的user信息,解密,转换成数组;查询数据库,在表friend中查出和user中uid一样的uid的一组数据;通过取出键形成新数组fuids,然后查询member中的在fuids包含着的uid的数据得到friend_list,然后在文中渲染。
<?php header("content-type:text/html;charset=utf-8"); //引入类 require_once __DIR__ . '/lib/common.php'; require_once __DIR__ . '/lib/Db.php'; require_once __DIR__ . '/lib/AES.php'; //通讯录朋友列表 //从cookie中取出user信息 $user_cookie = $_COOKIE['user']; //解密user信息 $aes = new AES(); $json = $aes->decrypt($user_cookie); $user = json_decode($json, true); //echo $user['uid']; //查出该用户的通讯录 $db = new Db(); $friends = $db->table('friend')->where(array('uid'=>$user['uid']))->cates('fuid'); $fuids = array_keys($friends); $friend_list = $db->table('member')->where('uid in('***plode(',', $fuids).')')->lists(); //print_r($friend_list); ?> <!DOCTYPE html> <html> <head> <title>通讯录</title> <!-- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">--> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css"> <script type="text/javascript" src="/static/layui/layui.js"></script> <script type="text/javascript" src="/static/js/jquery.min.js"></script> <script type="text/javascript" src="/static/js/jquery.cookie.js"></script> <!-- <script type="text/javascript" src="/static/js/chat.js"></script>--> <style type="text/css"> body{background: #f1f1f1;} .header-title{text-align: center;font-size: 1.2rem;color: #333;margin: 1.8rem;font-weight: bold;} .search input{text-align: center;border-radius: 4px;margin-bottom: 0.8rem;} .item li{margin-bottom: 1rem;} .item li p{width: 80%;border-bottom: 1px solid #efefef;padding-bottom: 1rem;font-size: 1rem;position: absolute;left: 4.5rem;margin-top: -2rem;} .menu-bottom{position: fixed;bottom: 0px;height: 4rem;background: #f1f1f1;width: 100%;} .menu-bottom .layui-col-xs3{text-align: center;padding-top: 0.5rem;} .menu-bottom .layui-col-xs3 i{font-size: 2rem;} .menu-bottom .layui-col-xs3 p{font-size: 0.5rem;} .menu-bottom .active{color: green;} .clear{clear: both;} .msg_list{padding: 0px 10px;} .msg_list .item{margin: 15px 0px;float: left;width: 100%} .msg_list .item .avatar{float: left;max-width: 20%;} .msg_list .item .userinfo{float: left;margin-left: 10px;max-width: 80%;} .msg_list .item .userinfo .username{color: #01AAED;} .msg_list .item .userinfo .times{font-size: 12px;color: gray;margin: 0px 5px;} .msg_list .item .userinfo .msg{margin-top: 5px;} .msg_list .item .userinfo .msg .layui-badge{padding:5px 10px;border-radius: 6px;} .msg_list .me .avatar{float: right;max-width: 20%;} .msg_list .me .userinfo{float: right;margin-right: 10px;max-width: 80%;} .msg_list .me p span{float: right;} .msg_list .me .msg{float: right;} .msg_list .groups img{width: 15px;height: 15px;float: left;} .emoticon{float: left;padding: 10px;} .emoticon ul{width: 265px;margin: 0 auto;float: left;} .emoticon ul li{list-style: none;display: inline;float: left;padding: 5px;border: solid 1px #cdcdcd;margin-left: -1px;margin-top: -1px;} .emoticon ul li:hover{background: #efefef;} </style> </head> <body> <input type="hidden" id="ws_uid"> <div class="header-title">通讯录<i class="layui-icon" style="float: right;"></i></div> <!--搜索--> <div class="layui-form layui-container search"> <input type="text" class="layui-input" name="" placeholder="搜索"> </div> <!--联系人--> <div class="layui-card"> <div class="layui-card-body"> <ul class="item"> <li> <img src="/static/image/add.png"> <p>新的朋友</p> </li> <li onclick="chat_group()"> <img src="/static/image/group.png"> <p>群聊</p> </li> <li> <img src="/static/image/label.png"> <p>标签</p> </li> <li> <img src="/static/image/public.png"> <p>公众号</p> </li> </ul> </div> </div> <div class="layui-card" style="margin-bottom: 5rem;overflow-y: auto;"> <div class="layui-card-body"> <ul class="item"> <?php foreach($friend_list as $friend){?> <li onclick="chating(<?php echo $friend['uid']?>)"> <img src="<?php echo $friend['avatar']?>"> <p><?php echo $friend['nickname']?></p> </li> <?php }?> </ul> </div> </div> <!--tab菜单--> <div class="menu-bottom layui-container"> <div class="layui-col-xs3" onclick="window.location.href='weixin.php'"><i class="layui-icon"></i><p>微信</p></div> <div class="layui-col-xs3 active"><i class="layui-icon"></i><p>通讯录</p></div> <div class="layui-col-xs3"><i class="layui-icon"></i><p>发现</p></div> <div class="layui-col-xs3"><i class="layui-icon"></i><p>我</p></div> </div> </body> </html> <script type="text/javascript"> layui.use(['layer'],function(){ // 连接并监听websocket // Chat.listen(); }); // 群聊 function chat_group(){ chating(0); } // 和TA聊天 function chating(uid){ $.get('/chat.php',{uid:uid},function(res){ layer.open({ type: 1, title: false, closeBtn: 0, area: ['100%', '100%'], content:res }); },'text'); } chat(); function chat(){ var ws = new WebSocket('ws:127.0.0.1:2000'); ws.onopen = function () { ws.send('I`m jay'); } ws.onmessage = function (ev) { console.log(ev.data); } } </script>
点击 "运行实例" 按钮查看在线实例
三、workman的安装与客户端的基本数据传递
下载workman,然后解压放在chat_server下的workman,做好环境配置(这里花了好些功夫,根据官网添加了插件,不知道怎么的好了)在workman目录下新建test.php,将官网里的简单案例复制下来,命令行cd到workman目录 然后 输入 php test.php start,用来测试workman是否正常工作。
然后在index添加js做基本的数据传递。
chat(); function chat(){ var ws = new WebSocket('ws:127.0.0.1:2000'); ws.onopen = function () { ws.send('I`m jay'); } ws.onmessage = function (ev) { console.log(ev.data); } }
点击 "运行实例" 按钮查看在线实例
四、总结
workman作为websocket的服务器框架速度快,承载大,这里浏览器作为客户端可以同workman服务器端进行交互,而且是长链接,一直保持通讯,用来监听客户端甚至是服务器的各种状态,用来做实时通讯;
layui学的不好 需要多巩固 尤其是layui和jquery共存的需要注意的一些点