Comment implémenter la fonction de chat en php
Comment implémenter la fonction de chat en php
1 Utilisez Ajax sur le front-end pour interroger régulièrement le script php, et php interrogera. les données du chat et les renvoient au front-end, et enfin le front-end les restitue
Exemple de code :
<html> <head> <title>聊天室</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="../jquery.min.js"></script> <script> $(function(){ $("#post").click(function(){ var content=$("#content").val(); if(!$.trim(content)){ alert('请填写内容'); return false; } $("#content").val(""); $.post("ajax.php", {content:content});}); }) function getData(msg){ if(msg == undefined) { msg = ''; } $.post("get.php",{"msg":msg},function(data){ //var myjson = eval("("+data+")"); if(data){ var chatcontent = ''; var obj = eval('('+data+')'); $.each(obj,function(key,val){ chatcontent += "<div class='username'>"+val['username']+" 说:</div>"; chatcontent += "<div class='content'>"+val['content']+"</div>"; }) $("#chatshow").html(chatcontent); } getData(); }) } // function getUser(msg){ // if(msg == undefined){ // msg = ''; // } // $.post("getuser.php",{"msg":msg},function(data){ // //var myjson = eval("("+data+")"); // if(data){ // var chatcontent = ''; // var obj = eval('('+data+')'); // $.each(obj,function(key,val){ // chatcontent += "<div class='username'>"+val['username']+" 说:</div>"; // chatcontent += "<div class='content'>"+val['content']+"</div>"; // }) // $("#chatshow").html(chatcontent); // } // getData(); // }) // } getData("one"); // $(function(){ // $("#userlist p").click(function(){ // $("#content").val("@"+$(this).text()+" "); // }) // }) // $(function(){ // $(document).keypress(function(e){ // if(e.ctrlKey && e.which == 13 || e.which == 10) { // var content=$("#content").val(); // if(!$.trim(content)){ // alert('请填写内容'); // return false; // } // $("#content").val(""); // $.post("ajax.php", {content:content}); // } // }) // //alert(event.clientX+document.body.clientWidth); // }) /*window.onbeforeunload=function (){ //return("===onbeforeunload==="); if(event.clientX>document.body.clientWidth && event.clientY < 0 || event.altKey){ return("你关闭了浏览器"); }else{ return(document.body.clientWidth); } } */ </script> <style> #chat{margin:0 auto;} #chatshow{width:500px;height:400px;overflow:auto;border:1px solid #ccc;float:left;} #userlist{width:100px;height:400px;overflow:auto;border:1px solid #ccc;float:left;margin-right:2px;} #userlist p{color:#0F0; cursor:pointer;} .clearboth{clear:both;} .username{font-weight:bold;color:#00F;font-size:12px;margin-bottom:3px;margin-top:8px;} </style> </head> <body> <div id="chat"> <div id="userlist"> <div style="font-size:12px;font-weight:bold;">在线用户列表</div> <div class="userlist"> <?php // $dsn = "mysql:host=localhost;dbname=test;charset=utf8'"; // $db = new PDO($dsn, 'root', 'root'); $db = new PDO('mysql:dbname=test;host=127.0.0.1;charset=utf8', 'root', 'adminroot'); $rs = $db->prepare("select * from chat where is_login = '1'"); $rs->execute(); while($row = $rs->fetch()){ echo '<p>'.$row['username'].'</p>'; } ?> </div> </div> <div id="chatshow"></div> </div> <div class="clearboth"></div> <div> <textarea name="content" id="content" style="width:600px;height:100px"></textarea> <input type='button' name='tj' id="post" value='发布' > </div> </body> </html>
<?php /*session_start(); $mem = new Memcache; $mem->connect("localhost",11211); if(isset($_POST['content'])){ $con['username'] = $_SESSION["username"]; $con['content'] = $_POST["content"]; $data = $mem->get('chat'); $data[] = $con; $mem->set("chat",$data,0,0); } $mem->close(); */ if(isset($_POST['content'])){ session_start(); $filename = date("Ymd",time()).".txt"; if(file_exists($filename)){ $content = file_get_contents($filename); $data = json_decode($content,true); $con['username'] = $_SESSION["username"]; $con['content'] = $_POST["content"]; $data[] = $con; $file = fopen($filename,"w"); fwrite($file,json_encode($data)); fclose($file); }else{ $file = fopen($filename,"w"); $con['username'] = $_SESSION["username"]; $con['content'] = $_POST["content"]; $data[] = $con; fwrite($file,json_encode($data)); fclose($file); } } ?>
<?php /*require 'conn.inc'; function getData(){ $sql="SELECT count(*) FROM `talkroom`"; $res=mysql_query($sql); $count = mysql_fetch_row($res); return $count; } $old = getData(); while(true){ $new = getData(); if($new[0]>$old[0]){ //echo json_encode($new['data']); //print_r($new); echo '2222222222'.'<br/>'; } //echo '<br />11111111111111111111111111111111111111111111111111111111111111111111'; usleep(1000); } */ /*set_time_limit(0); $mem = new Memcache; $mem->connect("localhost",11211); $count = count($mem->get("chat")); $com = true; //$mem->delete('chat'); if($_POST['msg'] == "one"){ exit(json_encode($mem->get("chat"))); } if($_POST['msg'] == "break"){ $com = false; } $time1 = time(); while(true){ if($com){ $data = $mem->get("chat"); if(count($data)>$count){ echo json_encode($data); break; } usleep(300); }else{ break; } } $mem->close();*/ set_time_limit(0); $filename = date("Ymd",time()).".txt"; if(file_exists($filename)){ $content = file_get_contents($filename); $data = json_decode($content,true); $count = count($data); // echo $count;die; if($_POST['msg'] == "one"){ exit(json_encode($data)); } while(true){ $contents = file_get_contents($filename); $datas = json_decode($contents,true); $counts = count($datas); if($counts>$count){ echo json_encode($datas); break; } usleep(300); } }else{ $file = fopen($filename,"w"); $con['username'] = "系统消息"; $con['content'] = "欢迎来到EPGO聊天室"; $data[] = $con; fwrite($file,json_encode($data)); fclose($file); exit(json_encode($data)); } ?>
2. Utilisez WebSocket pour établir une longue connexion avec le serveur à implémenter. la fonction de discussion.
Code client :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>websocket聊天室</title> <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600" rel="stylesheet"> <link rel="stylesheet" href="css/reset.min.css"> <link rel="stylesheet" href="css/style.css"> <style> .message img { float: left; width: 40px; height: 40px; margin-right: 12px; border-radius: 50%; } .you { margin-left: 60px; margin-top: -39px; } .me-header { float: right !important; margin-right: 0 !important; } .me { margin-right: 60px; margin-top: -39px; } .active-chat::-webkit-scrollbar, .left::-webkit-scrollbar { width: 2px; } </style> </head> <body> <div> <div> <div> <div style="padding: 20px 29px;height: auto;"> <div class="" style="font: 400 13.3333px Arial;font-weight: 400;">在线人数:<span id="numbers">0</span> 人 </div> </div> <ul> </ul> </div> <div> <div><span>Tips: <span>PHP之websocket聊天室</span></span></div> <div class="chat active-chat" data-chat="person1" style="height: auto;border-width: 0px;padding: 10px;height: 483px; padding: 10px;overflow-y: auto;scrollTop: 100px"> </div> <div> <a href="javascript:;" class="write-link attach"></a> <input type="text" id="input-value" onkeydown="confirm(event)"/> <a href="javascript:;" class="write-link smiley"></a> <a href="javascript:;" class="write-link send" onclick="send()"></a> </div> </div> </div> </div> <script src="js/index.js"></script> <script> var uname = prompt('请输入用户名', 'user' + uuid(8, 16)); var avatar = ['bo-jackson.jpg', 'dog.png', 'drake.jpg', 'louis-ck.jpeg', 'michael-jordan.jpg', 'thomas.jpg']; if (avatar[Math.round(Math.random() * 10)]) { var headerimg = "img/" + avatar[Math.round(Math.random() * 10)]; } else { var headerimg = "img/" + avatar[0]; } // 创建一个 websocket 连接 var ws = new WebSocket("ws://127.0.0.1:1238"); // websocket 创建成功事件 ws.onopen = function () { var data = "系统消息:建立连接成功"; console.log(data); }; // websocket 接收到消息事件 ws.onmessage = function (e) { var data = JSON.parse(e.data); switch (data.type) { case 'handShake': console.log(data.msg); //发送用户登录 var user_info = {'type': 'login', 'msg': uname, 'headerimg': headerimg}; sendMsg(user_info); break; case 'login': userList(data.user_list); systemMessage('系统消息: ' + data.msg + ' 已上线'); break; case 'logout': userList(data.user_list); if (data.msg.length > 0) { systemMessage('系统消息: ' + data.msg + ' 已下线'); } break; case 'user': messageList(data); break; case 'system': systemMessage(); break; } } // websocket 错误事件 ws.onerror = function () { var data = "系统消息 : 出错了,请退出重试."; alert(data); }; function confirm(event) { var key_num = event.keyCode; if (13 == key_num) { send(); } else { return false; } } function systemMessage(msg) { var html = `<div> <span>` + msg + `</span> </div>`; var active_chat = document.querySelector('div.active-chat'); var oldHtml = active_chat.innerHTML; active_chat.innerHTML = oldHtml + html; active_chat.scrollTop = active_chat.scrollHeight; } function send() { var msg = document.querySelector("input#input-value").value; var reg = new RegExp("\r\n", "g"); msg = msg.replace(reg, ""); sendMsg({type: "user", msg: msg}); document.querySelector("input#input-value").value = ""; } function sendMsg(msg) { var data = JSON.stringify(msg); ws.send(data); } function userList(user) { var html = ''; for (var i = 0; i < user.length; i++) { html += `<li data-chat="person1"> <img src="` + user[i].headerimg + `" alt=""/> <span>` + user[i].username + `</span> <span>` + user[i].login_time + `</span> <span style="color: green;font-size: 7px;">在线</span> </li>`; } document.querySelector('ul.people').innerHTML = html; document.querySelector('span#numbers').innerHTML = user.length; } function messageList(data) { if (data.from == uname) { var html = `<div> <img src="` + data.headerimg + `" alt=""/> <div class="bubble me">` + data.msg + `</div> </div>`; } else { var html = `<div> <img src="` + data.headerimg + `" alt=""/> <div class="bubble you">` + data.msg + `</div> </div>`; } var active_chat = document.querySelector('div.active-chat'); var oldHtml = active_chat.innerHTML; active_chat.innerHTML = oldHtml + html; active_chat.scrollTop = active_chat.scrollHeight; } /** * 生产一个全局唯一ID作为用户名的默认值; * * @param len * @param radix * @returns {string} */ function uuid(len, radix) { var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); var uuid = [], i; radix = radix || chars.length; if (len) { for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]; } else { var r; uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; uuid[14] = '4'; for (i = 0; i < 36; i++) { if (!uuid[i]) { r = 0 | Math.random() * 16; uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; } } } return uuid.join(''); } </script> </body> </html>
Code serveur :
<?php /** * Created by PhpStorm. * User: 25754 * Date: 2019/4/23 * Time: 14:13 */ class socketServer { const LISTEN_SOCKET_NUM = 9; const LOG_PATH = "./log/"; private $_ip = "127.0.0.1"; private $_port = 1238; private $_socketPool = array(); private $_master = null; public function __construct() { $this->initSocket(); } private function initSocket() { try { //创建socket套接字 $this->_master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // 设置IP和端口重用,在重启服务器后能重新使用此端口; socket_set_option($this->_master, SOL_SOCKET, SO_REUSEADDR, 1); //绑定地址与端口 socket_bind($this->_master, $this->_ip, $this->_port); //listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接,其中的能存储的请求不明的socket数目。 socket_listen($this->_master, self::LISTEN_SOCKET_NUM); } catch (Exception $e) { $this->debug(array("code: " . $e->getCode() . ", message: " . $e->getMessage())); } //将socket保存到socket池中 $this->_socketPool[0] = array('resource' => $this->_master); $pid = getmypid(); $this->debug(array("server: {$this->_master} started,pid: {$pid}")); while (true) { try { $this->run(); } catch (Exception $e) { $this->debug(array("code: " . $e->getCode() . ", message: " . $e->getMessage())); } } } private function run() { $write = $except = NULL; $sockets = array_column($this->_socketPool, 'resource'); $read_num = socket_select($sockets, $write, $except, NULL); if (false === $read_num) { $this->debug(array('socket_select_error', $err_code = socket_last_error(), socket_strerror($err_code))); return; } foreach ($sockets as $socket) { if ($socket == $this->_master) { $client = socket_accept($this->_master); if ($client === false) { $this->debug(['socket_accept_error', $err_code = socket_last_error(), socket_strerror($err_code)]); continue; } //连接 $this->connection($client); } else { //接受数据 $bytes = @socket_recv($socket, $buffer, 2048, 0); if ($bytes == 0) { $recv_msg = $this->disconnection($socket); } else { if ($this->_socketPool[(int)$socket]['handShake'] == false) { $this->handShake($socket, $buffer); continue; } else { $recv_msg = $this->parse($buffer); } } $msg = $this->doEvents($socket, $recv_msg); echo($msg); socket_getpeername ( $socket , $address ,$port ); $this->debug(array( 'send_success', json_encode($recv_msg), $address, $port )); $this->broadcast($msg); } } } /** * 数据广播 * @param $data */ private function broadcast($data) { foreach ($this->_socketPool as $socket) { if ($socket['resource'] == $this->_master) { continue; } socket_write($socket['resource'], $data, strlen($data)); } } /** * 业务处理 * @param $socket * @param $recv_msg * @return string */ private function doEvents($socket, $recv_msg) { //联系我 } /** * socket握手 * @param $socket * @param $buffer * @return bool */ public function handShake($socket, $buffer) { $acceptKey = $this->encry($buffer); $upgrade = "HTTP/1.1 101 Switching Protocols\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Accept: " . $acceptKey . "\r\n\r\n"; // 写入socket socket_write($socket, $upgrade, strlen($upgrade)); // 标记握手已经成功,下次接受数据采用数据帧格式 $this->_socketPool[(int)$socket]['handShake'] = true; socket_getpeername ( $socket , $address ,$port ); $this->debug(array( 'hand_shake_success', $socket, $address, $port )); //发送消息通知客户端握手成功 $msg = array('type' => 'handShake', 'msg' => '握手成功'); $msg = $this->frame(json_encode($msg)); socket_write($socket, $msg, strlen($msg)); return true; } /** * 帧数据封装 * @param $msg * @return string */ private function frame($msg) { $frame = []; $frame[0] = '81'; $len = strlen($msg); if ($len < 126) { $frame[1] = $len < 16 ? '0' . dechex($len) : dechex($len); } else if ($len < 65025) { $s = dechex($len); $frame[1] = '7e' . str_repeat('0', 4 - strlen($s)) . $s; } else { $s = dechex($len); $frame[1] = '7f' . str_repeat('0', 16 - strlen($s)) . $s; } $data = ''; $l = strlen($msg); for ($i = 0; $i < $l; $i++) { $data .= dechex(ord($msg{$i})); } $frame[2] = $data; $data = implode('', $frame); return pack("H*", $data); } /** * 接受数据解析 * @param $buffer * @return mixed */ private function parse($buffer) { $decoded = ''; $len = ord($buffer[1]) & 127; if ($len === 126) { $masks = substr($buffer, 4, 4); $data = substr($buffer, 8); } else if ($len === 127) { $masks = substr($buffer, 10, 4); $data = substr($buffer, 14); } else { $masks = substr($buffer, 2, 4); $data = substr($buffer, 6); } for ($index = 0; $index < strlen($data); $index++) { $decoded .= $data[$index] ^ $masks[$index % 4]; } return json_decode($decoded, true); } // 提取 Sec-WebSocket-Key 信息 private function getKey($req) { $key = null; if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $req, $match)) { $key = $match[1]; } return $key; } //加密 Sec-WebSocket-Key private function encry($req) { $key = $this->getKey($req); return base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); } /** * 连接socket * @param $client */ public function connection($client) { socket_getpeername ( $client , $address ,$port ); $info = array( 'resource' => $client, 'userInfo' => '', 'handShake' => false, 'ip' => $address, 'port' => $port, ); $this->_socketPool[(int)$client] = $info; $this->debug(array_merge(['socket_connect'], $info)); } /** * 断开连接 * @param $socket * @return array */ public function disconnection($socket) { $recv_msg = array( 'type' => 'logout', 'msg' => @$this->_socketPool[(int)$socket]['username'], ); unset($this->_socketPool[(int)$socket]); return $recv_msg; } /** * 日志 * @param array $info */ private function debug(array $info) { $time = date('Y-m-d H:i:s'); array_unshift($info, $time); $info = array_map('json_encode', $info); file_put_contents(self::LOG_PATH . 'websocket_debug.log', implode(' | ', $info) . "\r\n", FILE_APPEND); } } new socketServer();
Tutoriel recommandé : "Tutoriel PHP"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

CakePHP est un framework open source pour PHP. Il vise à faciliter grandement le développement, le déploiement et la maintenance d'applications. CakePHP est basé sur une architecture de type MVC à la fois puissante et facile à appréhender. Modèles, vues et contrôleurs gu

Pour travailler sur le téléchargement de fichiers, nous allons utiliser l'assistant de formulaire. Voici un exemple de téléchargement de fichiers.

Visual Studio Code, également connu sous le nom de VS Code, est un éditeur de code source gratuit – ou environnement de développement intégré (IDE) – disponible pour tous les principaux systèmes d'exploitation. Avec une large collection d'extensions pour de nombreux langages de programmation, VS Code peut être c

CakePHP est un framework MVC open source. Cela facilite grandement le développement, le déploiement et la maintenance des applications. CakePHP dispose d'un certain nombre de bibliothèques pour réduire la surcharge des tâches les plus courantes.

Ce tutoriel montre comment traiter efficacement les documents XML à l'aide de PHP. XML (Language de balisage extensible) est un langage de balisage basé sur le texte polyvalent conçu à la fois pour la lisibilité humaine et l'analyse de la machine. Il est couramment utilisé pour le stockage de données et

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,
