初始化
parent
2735fcfd16
commit
f3349ffb84
42
README.md
42
README.md
|
@ -1,36 +1,22 @@
|
||||||
# Introduction
|
# Hyperf-Chat
|
||||||
|
|
||||||
This is a skeleton application using the Hyperf framework. This application is meant to be used as a starting place for those looking to get their feet wet with Hyperf Framework.
|
## 1、简介
|
||||||
|
|
||||||
# Requirements
|
这是一个使用Hyperf框架的开发的IM后端应用程序。此项目是 [LumenIM-Serve](https://github.com/gzydong/LumenIM-Serve) 的重构版本。
|
||||||
|
|
||||||
Hyperf has some requirements for the system environment, it can only run under Linux and Mac environment, but due to the development of Docker virtualization technology, Docker for Windows can also be used as the running environment under Windows.
|
## 2、项目Demo
|
||||||
|
|
||||||
The various versions of Dockerfile have been prepared for you in the [hyperf\hyperf-docker](https://github.com/hyperf/hyperf-docker) project, or directly based on the already built [hyperf\hyperf](https://hub.docker.com/r/hyperf/hyperf) Image to run.
|
- 地址: [http://im.gzydong.club](http://im.gzydong.club)
|
||||||
|
- 账号: 18798272054 或 18798272055
|
||||||
|
- 密码: admin123
|
||||||
|
|
||||||
When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements:
|
## 3、环境要求
|
||||||
|
|
||||||
- PHP >= 7.2
|
- PHP >= 7.2
|
||||||
- Swoole PHP extension >= 4.4,and Disabled `Short Name`
|
- Swoole >= 4.4
|
||||||
- OpenSSL PHP extension
|
- OpenSSL
|
||||||
- JSON PHP extension
|
- JSON
|
||||||
- PDO PHP extension (If you need to use MySQL Client)
|
- PDO
|
||||||
- Redis PHP extension (If you need to use Redis Client)
|
- Redis >= 5.0.0
|
||||||
- Protobuf PHP extension (If you need to use gRPC Server of Client)
|
|
||||||
|
|
||||||
# Installation using Composer
|
## 4、项目安装
|
||||||
|
|
||||||
The easiest way to create a new Hyperf project is to use Composer. If you don't have it already installed, then please install as per the documentation.
|
|
||||||
|
|
||||||
To create your new Hyperf project:
|
|
||||||
|
|
||||||
$ composer create-project hyperf/hyperf-skeleton path/to/install
|
|
||||||
|
|
||||||
Once installed, you can run the server immediately using the command below.
|
|
||||||
|
|
||||||
$ cd path/to/install
|
|
||||||
$ php bin/hyperf.php start
|
|
||||||
|
|
||||||
This will start the cli-server on port `9501`, and bind it to all network interfaces. You can then visit the site at `http://localhost:9501/`
|
|
||||||
|
|
||||||
which will bring up Hyperf default home page.
|
|
||||||
|
|
|
@ -10,14 +10,13 @@ use Hyperf\Amqp\Message\ConsumerMessage;
|
||||||
use PhpAmqpLib\Message\AMQPMessage;
|
use PhpAmqpLib\Message\AMQPMessage;
|
||||||
use Hyperf\Amqp\Message\Type;
|
use Hyperf\Amqp\Message\Type;
|
||||||
use Hyperf\Amqp\Builder\QueueBuilder;
|
use Hyperf\Amqp\Builder\QueueBuilder;
|
||||||
use Hyperf\Server\Server;
|
|
||||||
use Hyperf\Server\ServerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Consumer()
|
* @Consumer(name="IM信息消费")
|
||||||
*/
|
*/
|
||||||
class DemoConsumer extends ConsumerMessage
|
class ImMessageConsumer extends ConsumerMessage
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 交换机名称
|
* 交换机名称
|
||||||
*
|
*
|
||||||
|
@ -32,13 +31,6 @@ class DemoConsumer extends ConsumerMessage
|
||||||
*/
|
*/
|
||||||
public $type = Type::FANOUT;
|
public $type = Type::FANOUT;
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定的队列名称
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $queue = 'im:message:queue';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由key
|
* 路由key
|
||||||
*
|
*
|
||||||
|
@ -46,6 +38,11 @@ class DemoConsumer extends ConsumerMessage
|
||||||
*/
|
*/
|
||||||
public $routingKey = 'consumer:im:message';
|
public $routingKey = 'consumer:im:message';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->setQueue('im:message:queue:'.config('ip_address'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重写创建队列生成类
|
* 重写创建队列生成类
|
||||||
*
|
*
|
||||||
|
@ -67,8 +64,7 @@ class DemoConsumer extends ConsumerMessage
|
||||||
*/
|
*/
|
||||||
public function consumeMessage($data, AMQPMessage $message): string
|
public function consumeMessage($data, AMQPMessage $message): string
|
||||||
{
|
{
|
||||||
echo $data;
|
echo PHP_EOL.$data;
|
||||||
echo PHP_EOL;
|
|
||||||
|
|
||||||
$server = server();
|
$server = server();
|
||||||
foreach (server()->connections as $fd){
|
foreach (server()->connections as $fd){
|
|
@ -31,4 +31,10 @@ class IndexController extends AbstractController
|
||||||
'message' => "Hello {$user}."
|
'message' => "Hello {$user}."
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function upload(ResponseInterface $response){
|
||||||
|
return [
|
||||||
|
'method' => 'upload',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,28 @@ use Hyperf\Contract\OnOpenInterface;
|
||||||
use Swoole\Http\Request;
|
use Swoole\Http\Request;
|
||||||
use Swoole\Websocket\Frame;
|
use Swoole\Websocket\Frame;
|
||||||
|
|
||||||
use Swoole\Server;
|
|
||||||
use Swoole\WebSocket\Server as WebSocketServer;
|
|
||||||
|
|
||||||
use Hyperf\Amqp\Producer;
|
use Hyperf\Amqp\Producer;
|
||||||
use App\Amqp\Producer\DemoProducer;
|
use App\Amqp\Producer\DemoProducer;
|
||||||
|
|
||||||
|
|
||||||
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
|
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
|
||||||
{
|
{
|
||||||
public function onMessage($server, Frame $frame): void
|
public function onMessage($server, Frame $frame): void
|
||||||
{
|
{
|
||||||
$producer = container()->get(Producer::class);
|
$producer = container()->get(Producer::class);
|
||||||
$producer->produce(new DemoProducer('test'. date('Y-m-d H:i:s')));
|
|
||||||
|
|
||||||
//$server->push($frame->fd, 'Recv: ' . $frame->data);
|
$ip = config('ip_address');
|
||||||
|
$producer->produce(new DemoProducer("我是来自[{$ip} 服务器的消息],{$frame->data}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onClose($server, int $fd, int $reactorId): void
|
public function onClose($server, int $fd, int $reactorId): void
|
||||||
{
|
{
|
||||||
var_dump('closed');
|
echo PHP_EOL."FD : 【{$fd}】 已断开...";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onOpen($server, Request $request): void
|
public function onOpen($server, Request $request): void
|
||||||
{
|
{
|
||||||
$server->push($request->fd, 'Opened');
|
$ip = config('ip_address');
|
||||||
|
$server->push($request->fd, "成功连接[{$ip}],IM 服务器");
|
||||||
|
echo PHP_EOL."FD : 【{$request->fd}】 成功连接...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Middleware;
|
||||||
|
|
||||||
|
use Hyperf\Utils\Context;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\Http\Server\MiddlewareInterface;
|
||||||
|
use Psr\Http\Server\RequestHandlerInterface;
|
||||||
|
|
||||||
|
class CorsMiddleware implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||||
|
{
|
||||||
|
$response = Context::get(ResponseInterface::class);
|
||||||
|
$response = $response->withHeader('Access-Control-Allow-Origin', '*')
|
||||||
|
->withHeader('Access-Control-Allow-Credentials', 'true')
|
||||||
|
// Headers 可以根据实际情况进行改写。
|
||||||
|
->withHeader('Access-Control-Allow-Headers', 'DNT,Keep-Alive,User-Agent,Cache-Control,Content-Type,Authorization');
|
||||||
|
|
||||||
|
Context::set(ResponseInterface::class, $response);
|
||||||
|
|
||||||
|
if ($request->getMethod() == 'OPTIONS') {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler->handle($request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,8 +46,8 @@ return [
|
||||||
'max_coroutine' => 100000,
|
'max_coroutine' => 100000,
|
||||||
'open_http2_protocol' => true,
|
'open_http2_protocol' => true,
|
||||||
'max_request' => 100000,
|
'max_request' => 100000,
|
||||||
'socket_buffer_size' => 2 * 1024 * 1024,
|
'socket_buffer_size' => 3 * 1024 * 1024,
|
||||||
'buffer_output_size' => 2 * 1024 * 1024,
|
'buffer_output_size' => 3 * 1024 * 1024,
|
||||||
],
|
],
|
||||||
'callbacks' => [
|
'callbacks' => [
|
||||||
SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
|
SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'],
|
||||||
|
|
|
@ -16,6 +16,9 @@ return [
|
||||||
'app_name' => env('APP_NAME', 'skeleton'),
|
'app_name' => env('APP_NAME', 'skeleton'),
|
||||||
'app_env' => env('APP_ENV', 'dev'),
|
'app_env' => env('APP_ENV', 'dev'),
|
||||||
'scan_cacheable' => env('SCAN_CACHEABLE', false),
|
'scan_cacheable' => env('SCAN_CACHEABLE', false),
|
||||||
|
|
||||||
|
'ip_address'=>env('IP_ADDRESS', ''),
|
||||||
|
|
||||||
StdoutLoggerInterface::class => [
|
StdoutLoggerInterface::class => [
|
||||||
'log_level' => [
|
'log_level' => [
|
||||||
LogLevel::ALERT,
|
LogLevel::ALERT,
|
||||||
|
|
|
@ -10,9 +10,14 @@ declare(strict_types=1);
|
||||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
use Hyperf\HttpServer\Router\Router;
|
use Hyperf\HttpServer\Router\Router;
|
||||||
|
use App\Middleware\CorsMiddleware;
|
||||||
|
|
||||||
|
|
||||||
Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController@index');
|
Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController@index');
|
||||||
|
|
||||||
|
Router::post('/upload', 'App\Controller\IndexController@upload',['middleware' => [CorsMiddleware::class]]);
|
||||||
|
|
||||||
|
|
||||||
Router::get('/favicon.ico', function () {
|
Router::get('/favicon.ico', function () {
|
||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
|
@ -21,4 +26,4 @@ Router::get('/favicon.ico', function () {
|
||||||
|
|
||||||
Router::addServer('ws', function () {
|
Router::addServer('ws', function () {
|
||||||
Router::get('/', 'App\Controller\WebSocketController');
|
Router::get('/', 'App\Controller\WebSocketController');
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<input type="file" name="filename" id="upload-btn"/>
|
||||||
|
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$('#upload-btn').on('change', function (file) {
|
||||||
|
var file = $(this)[0].files[0];
|
||||||
|
var fileData = new FormData();
|
||||||
|
fileData.append("file", file);
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
var func = function () {
|
||||||
|
if (i >= 20) {return;}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: 'http://47.105.180.123:9503/upload',
|
||||||
|
data: fileData,
|
||||||
|
dataType: 'json', //服务器返回json格式数据
|
||||||
|
type: 'post', //HTTP请求类型
|
||||||
|
processData: false,
|
||||||
|
success: function () {
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue