demand analysis
To achieve real-time communication on the web site one can view offline messages and chats, news alerts.
Core Technology
html5 of websocket, php extensions of swoole http://wiki.swoole.com/
data sheet
TABLE `msg` the CREATE ( ` id` int (. 11) the AUTO_INCREMENT the NOT NULL, `content` VARCHAR (255) the NOT NULL the DEFAULT '' the COMMENT 'content', ` tid` int (. 11) the NOT NULL the DEFAULT '0' the COMMENT 'received user ID ', `fid` int (. 11) the NOT NULL the DEFAULT' 0 'the COMMENT' transmits the user ID ', a PRIMARY KEY (` id`) ) ENGINE = 29 = the InnoDB the AUTO_INCREMENT the DEFAULT the CHARSET = UTF8 the COMMENT =' message table ';
TABLE `fd` the CREATE ( ` id` int (. 11) the AUTO_INCREMENT the NOT NULL, `uid` int (. 11) the NOT NULL the DEFAULT '0' the COMMENT 'user ID', ` fd` int (. 11) the NOT NULL the DEFAULT '0' the COMMENT 'binding ID', a PRIMARY KEY ( `id`) ) ENGINE =. 11 = the InnoDB the AUTO_INCREMENT the DEFAULT the CHARSET = UTF8 the COMMENT = 'user binding';
Server-side code
<?php class Server { private $serv; private $conn = null; private static $fd = null; public function __construct() { $this->initDb(); $this->serv = new swoole_websocket_server("0.0.0.0", 9502); $this->serv->set(array( 'worker_num' => 8, 'daemonize' => false, 'max_request' => 10000, 'dispatch_mode' => 2, 'debug_mode' => 1 )); $this->serv->on('Open', array($this, 'onOpen')); $this->serv->on('Message', array($this, 'onMessage')); $this->serv->on('Close', array($this, 'onClose')); $this->serv->start(); } function onOpen($server, $req) { // $server->push($req->fd, json_encode(33)); } public function onMessage($server, $frame) { //$server->push($frame->fd, json_encode(["hello", "world"])); $pData = json_decode($frame->data); $data = array(); if (isset($pData->content)) { $tfd = $this->getFd($pData->tid); //获取绑定的fd $data = $this->add($pData->fid, $pData->tid, $pData->content); //保存消息 $server->push($tfd, json_encode($data));// push recipient } else { $ this-> unBind (null, $ pData-> fid); // first access, Clear data binding if ($ this-> bind ($ pData-> fid, $ frame-> fd)) {// tie given FD $ Data = $ this-> loadHistory ($ pData-> FID, $ pData-> TID); // loading history } the else { $ = Data Array ( "Content" => "could not bind fd"); } } $ Server-> push (Frame-$> FD, json_encode ($ Data)); // push sender } public function the onClose (Server $, $ FD) { $ this-> UNBIND ($ FD); echo . "Close Connection:" $ FD; } / ******************* / function initdb () { $ Conn = mysqli_connect ( "192.168.1.122", "root", "a123456"); if (!$conn) { die('Could not connect: ' . mysql_error()); } else { mysqli_select_db($conn, "test"); } $this->conn = $conn; } public function add($fid, $tid, $content) { $sql = "insert into msg (fid,tid,content) values ($fid,$tid,'$content')"; if ($this->conn->query($sql)) { $id = $this->conn->insert_id; $data = $this->loadHistory($fid, $tid, $id); return $data; } } public function bind($uid, $fd) { $sql = "insert into fd (uid,fd) values ($uid,$fd)"; if ($this->conn->query($sql)) { return true; } } public function getFd($uid) { $sql = "select * from fd where uid=$uid limit 1"; $row = ""; if ($query = $this->conn->query($sql)) { $data = mysqli_fetch_assoc($query); $row = $data['fd']; } return $row; } public function unBind($fd, $uid = null) { if ($uid) { $sql = "delete from fd where uid=$uid"; } else { $sql = "delete from fd where fd=$fd"; } if ($this->conn->query($sql)) { return true; } } public function loadHistory($fid, $tid, $id = null) { $and = $id ? " and id=$id" : ''; $sql = "select * from msg where ((fid=$fid and tid = $tid) or (tid=$fid and fid = $tid))" . $and; $data = []; if ($query = $this->conn->query($sql)) { while ($row = mysqli_fetch_assoc($query)) { $data[] = $row; } } return $data; } } // 启动服务器 $server = new Server();
Note: swoole_websocket_server is based on the long connection tcp only in support of cli mode.
Start the server
php Server.php
Client code
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"> <script src="jquery-2.1.1.min.js"></script> <script src="jquery.json.js"></script> <script type="text/javascript"> var fid = 1; //发送者uid var tid = 2; //接收者uid var exampleSocket = new WebSocket("ws://192.168.1.17:9502"); $(function () { exampleSocket.onopen = function (event) { console.log(event.data); initData(); //加载历史记录 }; exampleSocket.onmessage = function (event) { console.log(event.data); loadData ($ parseJSON (event.data). ); // record the message introduced, loading a new message } }) function SENDMSG () { var pData = { Content:. document.getElementById ( 'Content') value, FID: FID , TID: TID, } IF (pData.content == '') { Alert ( "message can not be empty"); return; } exampleSocket.send (. $ a toJSON (pData)); // send message } function initData ( ) { var pData = { FID: FID, TID: TID, } exampleSocket.send($.toJSON(pData)); //获取消息记录,绑定fd } function loadData(data) { for (var i = 0; i < data.length; i++) { var html = '<p>' + data[i].fid + '>' + data[i].tid + ':' + data[i].content + '</p>'; $("#history").append(html); } } </script> </head> <body> <div id="history" style="border: 1px solid #ccc; width: 100px; height: auto"> </div> <input type="text" id="content"> <button onclick="sendMsg()">发送</button> </body> </html>
ps1: a copy of another client, modify sender uid your receiver, you can simulate real-time chat.
ps2: This code has achieved the function of loading history
ps3: To increase news alerts, msg need to read a marked increase, then pushed to the recipient when
IF ($ Server-> Push ($ TFD, json_encode ($ Data))) { // read tag }
ps4: Then unmarked read the news that a new message alerts.
Original URL: https://www.cnblogs.com/zenghansen/p/5084738.html