摘要:一效果圖二目錄結(jié)構(gòu)存放圖片文件數(shù)據(jù)庫(kù)操作類(lèi)數(shù)據(jù)庫(kù)配置文件創(chuàng)建協(xié)議文件聊天首頁(yè)登錄頁(yè)面數(shù)據(jù)庫(kù)文件三數(shù)據(jù)庫(kù)結(jié)構(gòu)四代碼部分?jǐn)?shù)據(jù)庫(kù)配置文件數(shù)據(jù)庫(kù)操作類(lèi)
一、效果圖
二、目錄結(jié)構(gòu)
images : 存放圖片
js : js文件
swoole
|----action.php 數(shù)據(jù)庫(kù)操作類(lèi) |----config.php 數(shù)據(jù)庫(kù)配置文件 |----websocket.php swoole創(chuàng)建websocket協(xié)議文件
index.php : 聊天首頁(yè)
login.html : 登錄頁(yè)面
webqq.sql : SQL數(shù)據(jù)庫(kù)文件
三、數(shù)據(jù)庫(kù)結(jié)構(gòu)
四、代碼部分
4.1、config.php 數(shù)據(jù)庫(kù)配置文件
"127.0.0.1", "user"=>"root", "password"=>"4f54dd", "port"=>3306, "database"=>"webqq", "charset"=>"utf8" );
4.2、action.php數(shù)據(jù)庫(kù)操作類(lèi)
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文件
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} "; } 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} "; } }
4.4、index.php首頁(yè)聊天文件
window.location.href="login.html";"; } ?>webqq----swoole
好友列表
正在與..... 聊天 關(guān)閉
4.5、login.html 登錄文件
webqq----swoole
4.6、webqq.sql 數(shù)據(jù)結(jié)構(gòu)文件
-- 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值與用戶(hù)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 "昵稱(chēng)", `username` varchar(45) COLLATE utf8_unicode_ci NOT NULL COMMENT "登陸名稱(chēng)", `password` char(32) COLLATE utf8_unicode_ci NOT NULL COMMENT "登陸密碼", `login_time` datetime NOT NULL COMMENT "最后登陸時(shí)間", `login_num` int(10) unsigned DEFAULT "0" COMMENT "登陸次數(shù)", PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT="用戶(hù)列表"; -- 2018-03-27 10:05:35
4.7、服務(wù)器環(huán)境centos7 + mariadb + swoole + apache + php7
注意事項(xiàng):須安裝swoole擴(kuò)展,Linux服務(wù)器,PHP7+版本以上
進(jìn)行項(xiàng)目根目錄使用: php websocket.php 執(zhí)行該文件
源碼下載地址:https://pan.baidu.com/s/1sWY-...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28480.html
摘要:的異步并行高性能網(wǎng)絡(luò)通信引擎,使用純語(yǔ)言編寫(xiě),提供了語(yǔ)言的異步多線程服務(wù)器,異步網(wǎng)絡(luò)客戶(hù)端,異步,異步,數(shù)據(jù)庫(kù)連接池,,消息隊(duì)列,毫秒定時(shí)器,異步文件讀寫(xiě),異步查詢(xún)。內(nèi)置了服務(wù)器端客戶(hù)端服務(wù)器端。 swoole :http://www.swoole.com/PHP的異步、并行、高性能網(wǎng)絡(luò)通信引擎,使用純C語(yǔ)言編寫(xiě),提供了PHP語(yǔ)言的異步多線程服務(wù)器,異步TCP/UDP網(wǎng)絡(luò)客戶(hù)端,異步M...
摘要:一閱前熱身為了更加形象的說(shuō)明同步異步阻塞非阻塞,我們以小明去買(mǎi)奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應(yīng)結(jié)果發(fā)給相應(yīng)的連接請(qǐng)求處理完成因?yàn)榛冢悦總€(gè)可以處理無(wú)數(shù)個(gè)連接請(qǐng)求。如此,就輕松的處理了高并發(fā)。 一、閱前熱身 為了更加形象的說(shuō)明同步異步、阻塞非阻塞,我們以小明去買(mǎi)奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點(diǎn)在消息通知的方式上...
摘要:一閱前熱身為了更加形象的說(shuō)明同步異步阻塞非阻塞,我們以小明去買(mǎi)奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應(yīng)結(jié)果發(fā)給相應(yīng)的連接請(qǐng)求處理完成因?yàn)榛?,所以每個(gè)可以處理無(wú)數(shù)個(gè)連接請(qǐng)求。如此,就輕松的處理了高并發(fā)。 一、閱前熱身 為了更加形象的說(shuō)明同步異步、阻塞非阻塞,我們以小明去買(mǎi)奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點(diǎn)在消息通知的方式上...
閱讀 2741·2021-11-22 15:22
閱讀 1653·2021-11-22 14:56
閱讀 3629·2021-09-22 15:12
閱讀 2415·2021-09-02 15:41
閱讀 2139·2021-08-27 16:26
閱讀 1126·2019-08-30 15:55
閱讀 2151·2019-08-29 17:30
閱讀 680·2019-08-29 16:26