Swoole简单入门教程聊天系统
Swoole可以让PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。
一、使用Swoole实现在线聊天
建立服务端主程序
准备工作就绪后,我们开始来撸代码。
首先在项目目录:src/app/ 下建立Chat.php,用作Swoole服务端主程序。
Chat.php文件的主体结构是这样的:
namespace Shanhubei\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/logs/chatswoole.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";
}
public function onMessage(swoole_websocket_server $ws, $frame)
{
//$ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));
$connets = $ws->connections;
echo count($connets)."\n";
echo $frame->data. "\n";
if ($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));
}
}
public function onClose($ws, $fid)
{
echo "client {$fid} closed\n";
foreach ($ws->connections as $fd) {
$ws->push($fd, $fid. '已离开!');
}
}
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;
}
}
我们需要往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 == '美女') {
$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,代码如下:
require dirname(__DIR__) . '/vendor/autoload.php';
use Shanhubei\Swoole\Chat;
$opt = [
'daemonize' => true
];
$ws = new Chat($opt);
$ws->start();
然后运行以下代码启动服务端:php chatServer.php 如果一切正常,你可以netstat -lntp看一下,系统会监听进程名为swooleChat,端口为9504的服务。
启动客户端
我们使用HTML5的websocket客户端来连接服务端,本地建立wsClient.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Client</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="css/chat.css">
</head>
<body>
<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>
<!-- <div>
<div id="result"></div>
<form class="form-inline" action="">
<div class="form-group">
<input type="text" class="form-control" id="m" autocomplete="off" placeholder="请输入内容">
</div>
<button type="submit" class="btn btn-info">发送</button>
</form>
</div> -->
<script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script>
if ("WebSocket" in window) {
var ws = new WebSocket("ws://192.168.3.105:9504");
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 = document.createElement("img");
// img.src = window.URL.createObjectURL(e.data);
// result.appendChild(img);
// var d = window.URL.createObjectURL(e.data);
// console.log(d);
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 {
// var p = document.createElement("p");
// p.innerHTML = e.data;
// result.appendChild(p);
$('.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>
</body>
</html>
然后用浏览器打开wsClient.html,你可以看到一个聊天窗口,一开始会提示连接成功,然后你可以在输入框中输入你想说的话,如“美女”等等。
原文地址:https://blog.csdn.net/IT_bar/article/details/137554756
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!