摘要:一效果圖二目錄結構存放圖片文件數據庫操作類數據庫配置文件創建協議文件聊天首頁登錄頁面數據庫文件三數據庫結構四代碼部分數據庫配置文件數據庫操作類
一、效果圖
二、目錄結構
images : 存放圖片
js : js文件
swoole
|----action.php 數據庫操作類 |----config.php 數據庫配置文件 |----websocket.php swoole創建websocket協議文件
index.php : 聊天首頁
login.html : 登錄頁面
webqq.sql : SQL數據庫文件
三、數據庫結構
四、代碼部分
4.1、config.php 數據庫配置文件
"127.0.0.1", "user"=>"root", "password"=>"4f54dd", "port"=>3306, "database"=>"webqq", "charset"=>"utf8" );
4.2、action.php數據庫操作類
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首頁聊天文件
window.location.href="login.html";"; } ?>webqq----swoole
好友列表
正在與..... 聊天 關閉
4.5、login.html 登錄文件
webqq----swoole
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 執行該文件
源碼下載地址:https://pan.baidu.com/s/1sWY-...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28480.html
摘要:的異步并行高性能網絡通信引擎,使用純語言編寫,提供了語言的異步多線程服務器,異步網絡客戶端,異步,異步,數據庫連接池,,消息隊列,毫秒定時器,異步文件讀寫,異步查詢。內置了服務器端客戶端服務器端。 swoole :http://www.swoole.com/PHP的異步、并行、高性能網絡通信引擎,使用純C語言編寫,提供了PHP語言的異步多線程服務器,異步TCP/UDP網絡客戶端,異步M...
摘要:一閱前熱身為了更加形象的說明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應結果發給相應的連接請求處理完成因為基于,所以每個可以處理無數個連接請求。如此,就輕松的處理了高并發。 一、閱前熱身 為了更加形象的說明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點在消息通知的方式上...
摘要:一閱前熱身為了更加形象的說明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應結果發給相應的連接請求處理完成因為基于,所以每個可以處理無數個連接請求。如此,就輕松的處理了高并發。 一、閱前熱身 為了更加形象的說明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點在消息通知的方式上...
閱讀 2727·2021-11-22 15:22
閱讀 1631·2021-11-22 14:56
閱讀 3616·2021-09-22 15:12
閱讀 2403·2021-09-02 15:41
閱讀 2122·2021-08-27 16:26
閱讀 1113·2019-08-30 15:55
閱讀 2139·2019-08-29 17:30
閱讀 665·2019-08-29 16:26