一、效果图

二、目录结构

images : 存放图片

js : js文件

swoole

|----action.php 数据库操作类

|----config.php 数据库配置文件

|----websocket.php swoole创建websocket协议文件

index.php : 聊天首页

login.html : 登录页面

webqq.sql : SQL数据库文件

三、数据库结构

四、代码部分

4.1、config.php 数据库配置文件

$database = array(

'host'=>'127.0.0.1',

'user'=>'root',

'password'=>'4f54dd',

'port'=>3306,

'database'=>'webqq',

'charset'=>'utf8'

);

4.2、action.php数据库操作类

class Action

{

private $conn;

public function __construct()

{

require_once (__DIR__.'/config.php');

$this->conn = mysqli_connect($database['host'],$database['user'],$database['password'],$database['database']) or die ('Connect mysql failed ~~'.mysqli_connect_error());

}

//login

public function login($nickname,$username,$password)

{

session_start();

$sql = " select `id` from `users` where `username` = '{$username}' ";

if($query = $this->conn->query($sql)) {

$row = mysqli_fetch_assoc($query);

$now = date('Y-m-d H:i:s');

if($row['id']) {

$sql = " update `users` set `nickname` = '{$nickname}' , `username` = '{$username}' ,`password` = md5('{$password}') , `login_time` = '{$now}' , `login_num` = (`login_num` + 1) where `id` = {$row['id']} ";

} else {

$sql = " insert into `users` (`nickname`,`username`,`password`,`login_time`,`login_num`) values ('{$nickname}' , '{$username}' , md5('{$password}') , '{$now}' ,'1')";

}

$this->conn->query($sql);

$user_id = $this->conn->insert_id;

$_SESSION['uid'] = $row['id'] ? $row['id'] : $user_id;

$_SESSION['nickname'] = $nickname;

return 1;

} else {

return 0;

}

}

//add friend

public function addFriend($from_uid,$to_uid)

{

$sql = " select * from `friend` where `from_uid` = '{$from_uid}' and `to_uid` = '{$to_uid}' ";

if($query = $this->conn->query($sql)) {

$is_friend = mysqli_fetch_assoc($query);

if(!$is_friend['to_uid']){

if($from_uid == $to_uid) {

return 2;

} else {

$sql = " select `nickname` from `users` where `id` = '{$to_uid}' ";

$query = $this->conn->query($sql);

$ret = mysqli_fetch_assoc($query);

$nickname = $ret['nickname'];

if($nickname){

$sql = " insert into `friend` (`from_uid`,`to_uid`,`nickname`) values ('{$from_uid}','{$to_uid}','{$nickname}') ";

$this->conn->query($sql);

return array('to_uid'=>$to_uid,'nickname'=>$nickname);

} else {

return 3;

}

}

} else {

return 4;

}

} else {

return 0;

}

}

//friend lists

public function friendLists($from_uid)

{

$sql = " select `id`,`nickname` from `users` where `id` != '{$from_uid}' ";

if($query = $this->conn->query($sql)) {

$lists = [];

while ($row = mysqli_fetch_assoc($query)) {

$sql_1 = " select `fd` from `fd_tmp` where `uid` = '{$row['id']}' ";

$query_1 = $this->conn->query($sql_1);

$ret = mysqli_fetch_assoc($query_1);

$row['status'] = $ret['fd'] ? 'online' : 'offline' ;

$lists[] = $row;

}

return $lists;

} else {

return 0;

}

}

//load history message

public function loadHistory($from_uid,$to_uid)

{

$sql = " select `from_uid`,`to_uid`,`message`,`send_time` from `chat` where ( (`from_uid` = '{$from_uid}' and `to_uid` = '{$to_uid}') or (`to_uid` = '{$from_uid}' and `from_uid` = '{$to_uid}') ) order by `send_time` desc";

if($query = $this->conn->query($sql)) {

$message = [];

while ($row = mysqli_fetch_assoc($query)) {

$message[] = $row;

}

return $message;

} else {

return 0;

}

}

//send message

public function sendMessage($from_uid,$to_uid,$message)

{

$time = date('Y-m-d H:i:s');

$sql = " insert into `chat` (`from_uid`,`to_uid`,`message`,`send_time`) values ('{$from_uid}','{$to_uid}','{$message}','{$time}') ";

if($query = $this->conn->query($sql)) {

$last_id = $this->conn->insert_id;

return $last_id;

} else {

return 0;

}

}

//get fd

public function getFd($uid)

{

$sql = " select `fd` from `fd_tmp` where `uid` = '{$uid}' ";

if($query = $this->conn->query($sql)) {

$row = mysqli_fetch_assoc($query);

return $row['fd'] ? $row['fd'] : 0;

} else {

return 0;

}

}

//bind fd

public function bindFd($uid,$fd)

{

$sql = " insert into `fd_tmp` (`fd`,`uid`) values ('{$fd}','{$uid}') ";

if($this->conn->query($sql)) {

return $fd;

} else {

return 0;

}

}

//unbind fd

public function unbindFd($fd)

{

$sql = " delete from `fd_tmp` where `fd` = '{$fd}' ";

if($this->conn->query($sql)) {

return 1;

} else {

return 0;

}

}

public function __destruct()

{

mysqli_close($this->conn);

}

}

//process ajax request

if($_POST && isset($_POST['typ']))

{

$action = new Action();

switch ($_POST['typ']) {

case 'login':

$ret = $action->login($_POST['nickname'],$_POST['username'],$_POST['password']);

break;

case 'addFriend':

$ret = $action->addFriend($_POST['from_uid'],$_POST['to_uid']);

break;

case 'friendLists':

$ret = $action->friendLists($_POST['from_uid']);

break;

case 'loadHistory':

$ret = $action->loadHistory($_POST['from_uid'],$_POST['to_uid']);

break;

case 'sendMessage':

$ret = $action->sendMessage($_POST['from_uid'],$_POST['to_uid'],$_POST['message']);

break;

}

echo json_encode(array('data'=>$ret));

}

4.3、websocket.php文件

require_once(__DIR__.'/action.php');

new Websocket();

class Websocket

{

private $serv;

private $action;

public function __construct()

{

$this->action = new action();

$this->serv = new swoole_websocket_server('0.0.0.0',9502);

$this->serv->on('open',array($this,'onOpen'));

$this->serv->on('message',array($this,'onMessage'));

$this->serv->on('close',array($this,'onClose'));

$this->serv->start();

}

public function onOpen($server,$request)

{

echo "Welcome {$request->fd} \n";

}

public function onMessage($server,$request)

{

$data = json_decode($request->data);

$from_uid = $data->from_uid;

$to_uid = $data->to_uid;

$message = $data->message;

$this->action->unbindFd($from_uid);

$from_fd = $this->action->bindFd($from_uid,$request->fd);

if($from_fd) {

$to_fd = $this->action->getFd($to_uid);

if($to_fd) {

$server->push($to_fd,$message);

}

} else {

$server->push($request->fd,'bind from_fd failed ~~');

}

}

public function onClose($server,$fd)

{

$this->action->unbindFd($fd);

echo "Goodbye {$fd} \n";

}

}

4.4、index.php首页聊天文件

session_start();

if(!$_SESSION['nickname'] && !$_SESSION['uid']){

echo '';

}

?>

webqq----swoole

html,body{margin:0;padding: 0;background-color: #eee;background-image: url("./images/1.jpg") }

.userlists{width:280px;height: 620px;border:1px #222 solid;box-shadow:3px 3px 10px #222;border-radius:5px;margin:100px 0px 0px 100px;background-color: #fff}

.userlists-title{background-color: #222;color:#fff;height: 50px;padding-top:10px;text-align: center;border-radius: 5px 5px 0px 0px;position: relative;}

.lists_left{height: 500px;overflow-y:scroll;}

.lists_left::-webkit-scrollbar {display:none}

.lists_left ul,li{margin:0px;padding:0px;list-style: none}

.lists_left li{border-bottom: 1px #666 solid;height: 35px;line-height: 35px;}

.lists_left li a{text-decoration: none;color:#000;height: 100%;display: block;padding-left: 10px}

.tools{border-radius: 0px 0px 5px 5px;}

.h10{height: 10px;}

.h30{height: 500px}

.circular{height: 30px;width: 30px;border-radius: 30px;background-color: #fff;margin:0 auto;}

.find{height: 40px;line-height:40px;text-align:center;background-color: #ccc}

.find input{outline: none}

.dialogue{width: 600px;height: 600px;background-color: #fff;position: absolute;top:100px;left: 450px;border-radius: 5px;border:1px #222 solid;box-shadow:3px 5px 5px #222;border-radius:5px;display: none;}

.close{border:1px #fff solid;border-radius:5px;display: inline-block;width: 50px;height: 25px;line-height: 25px;position: absolute;right: 15px;top:12px;}

.send{height: 50px;line-height: 50px;background-color: #222;border-radius: 0px 0px 5px 5px;text-align: center; }

.send input[name='content']{height: 30px;width:480px;padding:0px 5px;outline: none}

.send input[name='sendBtn']{height: 34px;width:80px;display: inline-block;}

.chat-line{width:360px;border-radius: 10px;margin:10px;padding: 10px;word-wrap:break-word}

.from{border:1px red solid;float: right;}

.to{border:1px green solid;float: left;}

.all{position: absolute;top:0;right: 100px}

.scroll_box{position: relative;overflow-y:scroll;height: 500px};

.scroll_box::-webkit-scrollbar {display:none}

.lists {position: absolute;left: 0;top: 0;}

<?php echo $_SESSION['nickname'];?>
好友列表
正在与 ..... 聊天 关闭

$(function(){

$.post("./swoole/action.php",{from_uid:<?php echo $_SESSION['uid'];?>,typ:'friendLists'},function(res){

var r = eval("(" + res + ")");

if(r.data) {

var h = "";

for(var i = 0; i< r.data.length; i++) {

var status = r.data[i].status =="offline" ? "离线" : "在线" ;

h += '

' + r.data[i].nickname + "  ( " + status +' ) ';

}

$("#friend_lists").html(h);

}

});

$("#friend_lists").on("click",".friend",function(){

var to_uid = $(this).attr("data-id");

var nickname = $(this).attr("data-nickname");

$("#uname").html(nickname);

$("input[name='to_uid']").val(to_uid);

$.post("./swoole/action.php",{from_uid:<?php echo $_SESSION['uid'];?>,to_uid:to_uid,typ:"loadHistory"},function(res){

var r = eval("(" + res + ")");

if(r.data) {

var h = "";

for (var i = r.data.length - 1; i >= 0; i--) {

if(r.data[i].from_uid == <?php echo $_SESSION['uid'];?>) {

h += '

' + r.data[i].message + '

';

} else {

h += '

' + r.data[i].message + '

';

}

}

$("#chat-box").html(h);

srcollBox()

}

});

$(".dialogue").show();

});

$("#sendMessage").on("click",function(){

if($("input[name='content']").val()) {

srcollBox()

sendMessage();

} else {

alert("please input your message~");

}

});

$(document).keyup(function(evt){

if(evt.keyCode == 13) {

if($("input[name='content']").val()) {

srcollBox()

sendMessage();

} else {

alert("please input your message~");

}

}

});

$(".close").on("click",function(){

$(".dialogue").hide();

});

function srcollBox(){

var h = $(".lists").height();

$(".scroll_box").scrollTop(h,4000)

}

srcollBox();

if(window.WebSocket){

var ws = new WebSocket("ws://192.168.0.140:9502");

ws.onopen = function(evt){

console.log("Connect WebSocket succuess ~~ \n");

}

ws.onmessage = function(evt){

$("#chat-box").append('

' + evt.data + '

');

srcollBox();

console.log("message on server : " + evt.data + "\n");

}

ws.onclose = function(evt){

console.log("WebSocket closed ~~\n");

}

ws.onerror = function(evt){

console.log("Connect WebSocket failed ~~\n");

}

function sendMessage(){

var params = {

from_uid : <?php echo $_SESSION['uid'];?>,

to_uid : $("input[name='to_uid']").val(),

message : $("input[name='content']").val(),

typ : "sendMessage"

};

var msg = JSON.stringify(params);

$("#chat-box").append('

' + $("input[name='content']").val() + '

');

srcollBox();

$.post("./swoole/action.php",params,function(res){

var r = eval("(" + res + ")");

if(r.data) {

ws.send(msg);

} else {

alert("send message failed , insert mysql failed~~\n");

}

});

}

} else {

alert("Your browser does not support WebSocket !");

}

});

4.5、login.html 登录文件

webqq----swoole

html,body{margin:0;padding: 0;background-color: #eee}

.login-form{background-color: #fff;width: 500px;height: 500px;margin:100px auto;border:1px #ccc solid;border-radius: 5px;box-shadow: 3px 3px 3px #666}

h3{text-align: center;margin-top: 100px}

.container{text-align: center;margin-top: 30px;}

.container label{display: inline-block;width: 50px;}

.container input{display: inline-block;height: 25px;line-height: 25px;padding: 0px 5px;width: 300px;outline: none}

input[name='login']{background-color: #5aba1f;color:#fff;border:none;width: 150px;height: 30px;line-height: 30px;border-radius: 5px;margin-top: 30px;cursor: pointer;}

.warning{border:2px #f00 solid;}

WebQQ

昵称:
帐号:
密码:

$(function(){

$("input[name='login']").click(function(){

var nickname = $("input[name='nickname']").val();

var username = $("input[name='username']").val();

var password = $("input[name='password']").val();

if(nickname == ""){

alert("请设置昵称");

$("input[name='nickname']").focus();

$("input[name='nickname']").addClass("warning");

$("input[name='username']").removeClass("warning");

$("input[name='password']").removeClass("warning");

} else if(username == "") {

alert("请输入帐号");

$("input[name='username']").focus();

$("input[name='nickname']").removeClass("warning");

$("input[name='username']").addClass("warning");

$("input[name='password']").removeClass("warning");

} else if(password == "") {

alert("请输入密码");

$("input[name='password']").focus();

$("input[name='nickname']").removeClass("warning");

$("input[name='username']").removeClass("warning");

$("input[name='password']").addClass("warning");

} else {

$("input[name='nickname']").removeClass("warning");

$("input[name='username']").removeClass("warning");

$("input[name='password']").removeClass("warning");

$.post("./swoole/action.php",{nickname:nickname,username:username,password:password,typ:'login'},function(res){

var r = eval("(" + res + ")");

if(r.data == "1"){

window.location.href="index.php";

} else {

alert("failed~~");

}

});

}

});

});

4.6、webqq.sql 数据结构文件

-- Adminer 4.1.0 MySQL dump

SET NAMES utf8;

SET time_zone = '+00:00';

SET foreign_key_checks = 0;

SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';

DROP TABLE IF EXISTS `chat`;

CREATE TABLE `chat` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',

`from_uid` int(10) unsigned NOT NULL,

`to_uid` int(10) unsigned NOT NULL,

`message` varchar(255) COLLATE utf8_unicode_ci NOT NULL,

`send_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

DROP TABLE IF EXISTS `fd_tmp`;

CREATE TABLE `fd_tmp` (

`fd` int(10) unsigned NOT NULL,

`uid` int(10) unsigned NOT NULL

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='FD值与用户ID绑定';

DROP TABLE IF EXISTS `friend`;

CREATE TABLE `friend` (

`from_uid` int(10) unsigned DEFAULT NULL,

`to_uid` int(10) unsigned NOT NULL,

`nickname` varchar(45) COLLATE utf8_unicode_ci NOT NULL

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='好友列表';

DROP TABLE IF EXISTS `users`;

CREATE TABLE `users` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',

`nickname` varchar(45) COLLATE utf8_unicode_ci NOT NULL COMMENT '昵称',

`username` varchar(45) COLLATE utf8_unicode_ci NOT NULL COMMENT '登陆名称',

`password` char(32) COLLATE utf8_unicode_ci NOT NULL COMMENT '登陆密码',

`login_time` datetime NOT NULL COMMENT '最后登陆时间',

`login_num` int(10) unsigned DEFAULT '0' COMMENT '登陆次数',

PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户列表';

-- 2018-03-27 10:05:35

4.7、服务器环境centos7 + mariadb + swoole + apache + php7

注意事项:须安装swoole扩展,Linux服务器,PHP7+版本以上

进行项目根目录使用: php websocket.php 执行该文件

php mysql qq登录_php+swoole+mysql 仿webqq及时聊天相关推荐

  1. php mysql qq登录_php+js+mysql设计的仿webQQ-4登陆和注册

    <6>登陆验证 Js代码 function checkLogin() { var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+ ...

  2. php mysql emoji表情_php 让MySQL支持Emoji表情 mysql 5.5.3+

    让MySQL支持Emoji表情 mysql 5.5.3+ 让mysql支持Emoji表情,涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集. mysql 版本 5.6 1 解决 ...

  3. php+mysql投票代码_PHP+jQuery+MySql实现红蓝投票功能

    本文是一篇综合知识应用类文章,需要您具备PHP.jQuery.MySQL以及html和css方面的基本知识.本文在<PHP+MySql+jQuery实现的"顶"和" ...

  4. php连接mysql乱码原因_PHP连接MYSQL出现乱码的原因与解决办法

    PHP连接mysql出现乱码的原因与解决方法 解决MySql数据库乱码的一个首要前提是保证 数据库+数据表+前端显示 编码一致,国内项目一般统一设定为GB2312或GBK,而国际化项目则一般使用utf ...

  5. php 查询mysql数据库 打印_php 查询mysql数据库 打印

    用C语言操纵Mysql 原文:用C语言操纵Mysql 以下代码块是用来连接数据库的通讯过程,要连接MYSQL,必须建立MYSQL实例,通过mysql_init初始化方能开始进行连接. typedef ...

  6. php+swoole+mysql 仿webqq及时聊天

    一.效果图 二.目录结构 images : 存放图片 js : js文件 swoole |----action.php 数据库操作类 |----config.php 数据库配置文件 |----webs ...

  7. php mysql用户登录_php mysql实现用户登录功能的代码示例

    接着上次的php mysql添加用户的功能代码,今天来学习下php实现用户登录与注销的功能,通过跟踪session会话来保存用户的登陆状态. 1,登录页面 login.php 用户登录_www.# 用 ...

  8. php和mysql的概述_PHP的MySQL扩展:MySQL数据库概述_MySQL

    一.SQL:结构化查询语言 SQL(Structured Query Language)是高级的非过程化变成语言,专门用于查询和修改数据库的信息以及对数据库进行管理和维护的标准语言.SQL语言结构简单 ...

  9. php仿qq登录界面安卓,Android_Android仿QQ登陆窗口实现原理,今天根据腾讯qq,我们做一个 - phpStudy...

    Android仿QQ登陆窗口实现原理 今天根据腾讯qq,我们做一个练习,来学习如何制作一个漂亮的布局.首先看一下官方图片 还是一个启动画面,之后进入登录页面,导航页面就不介绍了,大家可以参考微信的导航 ...

最新文章

  1. HyperLogLog 算法的原理讲解以及 Redis 是如何应用它的
  2. android频繁点击ui崩溃,android easeui 集成 启动崩溃
  3. SQL Server 2005 Sa 用户的启用
  4. hdu 4495(hash+二分+dp)
  5. vivo9.0系统设备最简单激活XPOSED框架的步骤
  6. 苹果台式电脑怎么开机_龙华苹果电脑回收公司,台式电脑回收公司电话
  7. android meta工具,android ota 升级包制作分析 (5 工具)
  8. 技术能变现,才是硬道理
  9. 20145209 《信息安全系统设计基础》第14周学习总结
  10. Python学习总结(5)——字符串
  11. Python实现Excel随机抽取数
  12. 建筑CAD基础设计【2】
  13. 3个酷到没同学的冷门专业,开始逆袭了?
  14. 小米生态链的战投启示
  15. 解决Echarts的toolbox只显示英文的问题
  16. 狗子课堂 二 虚拟机配置
  17. 我和关注我的1w个粉丝“合影”啦–爬取上万个粉丝的数据并进行数据可视化分析,收获满满
  18. 区块链 : 历史、现在与未来
  19. JAVA毕业设计web家教管理系统计算机源码+lw文档+系统+调试部署+数据库
  20. python检查交换机端口状态_Python3 自动登录全部交换机查询MAC所在端口

热门文章

  1. mysql config type_请检查DNT.config中的DbType节点数据库类型是否正确例如:SqlServer的访问MYSQL...
  2. Python statsmodel包训练LR模型
  3. 从500万年薪签解说 看电竞泡沫论
  4. 机器学习(5): k-近邻算法(kNN) 小结及实验
  5. QQ日志“服务器繁忙,稍后再试”
  6. html+css+js:坚持30s小游戏
  7. Mysql prepare 用法
  8. 【Http2.0】Http2.0
  9. Invalidate用法
  10. python 爬取搞笑视频_爬取某视频网上的所有搞笑视频,喜欢做视频的小伙伴就有素材了...