内容简介:在线web聊天功能是基于WebSocket协议实现的,Swoole从1.7.9开始就增加了内置的WebSocket服务器支持,通过几行PHP代码就可以写出一个异步非阻塞多进程的WebSocket服务器。今天我给大家讲解如何使用Swoole实现一个简易的聊天功能。
在线web聊天功能是基于WebSocket协议实现的,Swoole从1.7.9开始就增加了内置的WebSocket服务器支持,通过几行 PHP 代码就可以写出一个异步非阻塞多进程的WebSocket服务器。今天我给大家讲解如何使用Swoole实现一个简易的聊天功能。
准备
请按照本站Swoole系列文章:Swoole实验室,搭建好项目,并安装Swoole扩展。Swoole版本建议在1.8+,当然2.x,4.0都可以。
如果您是新访客,请先参考本站文章:
建立核心服务Chat
准备工作就绪后,我们开始来撸代码。
首先在项目目录:src/App/ 下建立Chat.php,用作Swoole服务端主程序。
Chat.php文件的主体结构是这样的:
<?php namespace Helloweba\Swoole; use swoole_websocket_server; class Chat { protected $ws; protected $host = '0.0.0.0'; protected $port = 9504; // 进程名称 protected $taskName = 'swooleChat'; // PID路径 protected $pidFile = '/run/swooleChat.pid'; // 设置运行时参数 protected $options = [ 'worker_num' => 4, //worker进程数,一般设置为CPU数的1-4倍 'daemonize' => true, //启用守护进程 'log_file' => '/data/log/swoole.log', //指定swoole错误日志文件 'log_level' => 3, //日志级别 范围是0-5,0-DEBUG,1-TRACE,2-INFO,3-NOTICE,4-WARNING,5-ERROR 'dispatch_mode' => 1, //数据包分发策略,1-轮询模式 ]; public function __construct($options = []) { $this->ws = new swoole_websocket_server($this->host, $this->port); if (!empty($options)) { $this->options = array_merge($this->options, $options); } $this->ws->set($this->options); $this->ws->on("open", [$this, 'onOpen']); $this->ws->on("message", [$this, 'onMessage']); $this->ws->on("close", [$this, 'onClose']); } public function start() { // Run worker $this->ws->start(); } public function onOpen(swoole_websocket_server $ws, $request) { // 设置进程名 cli_set_process_title($this->taskName); //记录进程id,脚本实现自动重启 $pid = "{$ws->master_pid}\n{$ws->manager_pid}"; file_put_contents($this->pidFile, $pid); echo "server: handshake success with fd{$request->fd}\n"; } // 发送websocket消息 public function onMessage(swoole_websocket_server $ws, $frame) { //$ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s")); } public function onClose($ws, $fid) { echo "client {$fid} closed\n"; foreach ($ws->connections as $fd) { $ws->push($fd, $fid. '已离开!'); } } }
我们需要往 onMessage()
方法里填代码。在这里,服务端接收客户端消息,并作出相应动作。Websocket可以向客户端发送字符串、二进制等形式消息。
public function onMessage(swoole_websocket_server $ws, $frame) { //$ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s")); if ($frame->data == '图片') { $ws->push($frame->fd, file_get_contents('https://www.helloweba.net/images/hellowebanet.png'), WEBSOCKET_OPCODE_BINARY); } elseif ($frame->data == '美女') { $mmpic = [ 'http://pic15.photophoto.cn/20100402/0036036889148227_b.jpg', 'http://pic23.nipic.com/20120814/5914324_155903179106_2.jpg', 'http://pic40.nipic.com/20140403/8614226_162017444195_2.jpg' ]; $picKey = array_rand($mmpic); //随机返回一张图片 $ws->push($frame->fd, file_get_contents($mmpic[$picKey]), WEBSOCKET_OPCODE_BINARY); } else { $ws->push($frame->fd, $this->reply($frame->data)); } } private function reply($str) { $str = mb_strtolower($str); switch ($str) { case 'hello': $res = 'Hello, Friend.'; break; case 'fuck': $res = 'Fuck bitch.'; break; case 'ping': $res = 'PONG.'; break; case 'time': $res = date('H:i:s'); break; default: $res = $str; break; } return $res; }
将上面代码加入到Chat.php中,用来处理接收消息并响应回复。响应回复的内容可以根据实际情况修改,本代码只是用来演示。
启动服务端
在public/目录下建立chatServer.php,代码如下:
<?php require dirname(__DIR__) . '/vendor/autoload.php'; use Helloweba\Swoole\Chat; $opt = [ 'daemonize' => true ]; $ws = new Chat($opt); $ws->start();
然后运行以下代码启动服务端:
php chatServer.php
如果一切正常,你可以 netstat -lntp
看一下,系统会监听进程名为swooleChat,端口为9504的服务。
启动客户端
我们使用HTML5的websocket客户端来连接服务端,本地建立wsClient.html
<div id="chat-wrap"> <div id="result"></div> <ul class="chat-thread"> <li class="you"><img class="head" src="images/head1.jpg" alt=""><p>Are we meeting today?</p></li> <li class="you"><img class="head" src="images/head1.jpg" alt=""><p>yes</p></li> <li class="me"><img class="head" src="images/head1.jpg" alt=""><p>一部分保持在行尾,另一部分换到下一行。</p></li> <li class="you"><img class="head" src="images/head1.jpg" alt=""><p>yes</p></li> <li class="you"><img class="head" src="images/head1.jpg" alt=""><p>yes</p></li> </ul> </div> <div class="send"> <form action=""> <input type="text" class="form-control" id="m" autocomplete="off" placeholder="请输入内容"> <button type="submit" class="btn btn-info">发送</button> </form> </div> <script> if ("WebSocket" in window) { var ws = new WebSocket("ws://192.168.1.34:9504"); //这里ip地址为实际swoole服务地址,请修改 var result = document.querySelector('#result'); var chatthread = document.querySelector('.chat-thread'); chatthread.scrollTop = chatthread.scrollHeight; ws.onopen = function() { result.innerHTML = '已连接上!'; $('#result').show().html('已连接上!').fadeOut(1500); console.log('已连接上!'); } document.querySelector('form').onsubmit = function(e) { var msg = document.querySelector('#m').value; ws.send(msg); $('.chat-thread').append('<li class="me"><img class="head" src="images/head1.jpg" alt=""><p>'+msg+'</p></li>'); chatthread.scrollTop = chatthread.scrollHeight; document.querySelector('#m').value = ''; return false; } ws.onmessage = function(e) { if(e.data instanceof Blob) { var img = '<img src="'+window.URL.createObjectURL(e.data)+'" width="180"/>'; $('.chat-thread').append('<li class="you"><img class="head" src="images/head1.jpg" alt=""><p>'+img+'</p></li>'); }else { $('.chat-thread').append('<li class="you"><img class="head" src="images/head1.jpg" alt=""><p>'+e.data+'</p></li>'); } chatthread.scrollTop = chatthread.scrollHeight; } ws.onclose = function() { console.log('连接已关闭!'); } } else { alert('您的浏览器不支持 WebSocket!'); } </script>
然后用浏览器打开wsClient.html,你可以看到一个聊天窗口,一开始会提示连接成功,然后你可以在输入框中输入你想说的话,如“图片”,“美女”等等。
后记
本文讲述的代码是单一聊天,也就是说客户端和服务端是一一对应的。当然我们也可以实现一对多,即服务端可以给多个客户端发消息,就类似群聊。可以在Chat.php的 onMessage()
里修改。
以上所述就是小编给大家介绍的《Swoole实验室:4-使用Swoole实现在线聊天》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- workerman结合laravel开发在线聊天应用
- Vue2 全家桶仿 微信App 项目,支持多人在线聊天和机器人聊天
- Swoole跟thinkphp5结合开发WebSocket在线聊天通讯系统教程
- Ceph实验室:第四课:Ceph监控
- Ceph实验室:第四课:Ceph监控
- 2018Android实验室CV培训总结
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。