php实时聊天源码 仿手机QQ,php加swoole加mysql 仿webqq及时聊天

本篇文章的内容是php加swoole加mysql 仿webqq及时聊天 ,现在分享给大家,有需要的朋友可以参考一下

一、效果图

e586bf54f5e5f56fa7f33a6193c6bce8.png

58405555b673227ba32e36a04bf3e2f9.png

二、目录结构

8cb04dbbd418bcbcc18d0d0475b610c6.png

images : 存放图片

js : js文件

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

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

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

index.php : 聊天首页

login.html : 登录页面

webqq.sql : SQL数据库文件

三、数据库结构

42d19754bbda4c4bedabe30206440f21.png

四、代码部分

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

$database = array(

'host'=>'127.0.0.1',

'user'=>'root',

'password'=>'4f54dd',

'port'=>3306,

'database'=>'webqq',

'charset'=>'utf8'

);

4.2、action.php数据库操作类<?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文件<?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首页聊天文件<?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 执行该文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值