1、TCP服务器
//创建Server对象,监听 127.0.0.1:9501端口 $serv = new SwooleServer("127.0.0.1", 9501); //监听连接进入事件 $serv->on('Connect', function ($serv, $fd) { echo "Client: Connect. "; }); //监听数据接收事件 $serv->on('Receive', function ($serv, $fd, $from_id, $data) { $serv->send($fd, "Server: ".$data); }); //监听连接关闭事件 $serv->on('Close', function ($serv, $fd) { echo "Client: Close. "; }); //启动服务器 $serv->start();
- 通过监听端口来启动服务,通过监听事件来响应不同的逻辑(回调指定函数)。
- 服务器可以同时被成千上万个客户端连接,$fd
就是客户端连接的唯一标识符。
- swoole提供了异步处理功能,可以投递一个异步任务到 TaskWorker 进程池中执行,不影响当前请求的处理速度。
$serv = new SwooleServer("127.0.0.1", 9501); //设置异步任务的工作进程数量 $serv->set(array('task_worker_num' => 4)); //此回调函数在worker进程中执行 $serv->on('receive', function($serv, $fd, $from_id, $data) { //投递异步任务 $task_id = $serv->task($data); echo "Dispatch AsyncTask: id=$task_id "; }); //处理异步任务(此回调函数在task进程中执行) $serv->on('task', function ($serv, $task_id, $from_id, $data) { echo "New AsyncTask[id=$task_id]".PHP_EOL; //返回任务执行的结果 $serv->finish("$data -> OK"); }); //处理异步任务的结果(此回调函数在worker进程中执行) $serv->on('finish', function ($serv, $task_id, $data) { echo "AsyncTask[$task_id] Finish: $data".PHP_EOL; }); $serv->start();
2、UDP服务器
//创建Server对象,监听 127.0.0.1:9502端口,类型为SWOOLE_SOCK_UDP $serv = new SwooleServer("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); //监听数据接收事件 $serv->on('Packet', function ($serv, $data, $clientInfo) { $serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data); var_dump($clientInfo); }); //启动服务器 $serv->start();
- UDP没有连接的概念,客户端无需connect,直接向监听端口发送数据包。
3、http服务器
$http = new SwooleHttpServer("0.0.0.0", 9501); $http->on('request', function ($request, $response) { var_dump($request->get, $request->post); $response->header("Content-Type", "text/html; charset=utf-8"); $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); }); $http->start();
- HTTP
服务器只需要关注请求响应即可,所以只需要监听一个 onRequest 事件。
4、webSocket服务器
//创建websocket服务器对象,监听0.0.0.0:9502端口 $ws = new SwooleWebSocketServer("0.0.0.0", 9502); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request) { var_dump($request->fd, $request->get, $request->server); $ws->push($request->fd, "hello, welcome "); }); //监听WebSocket消息事件 $ws->on('message', function ($ws, $frame) { echo "Message: {$frame->data} "; $ws->push($frame->fd, "server: {$frame->data}"); }); //监听WebSocket连接关闭事件 $ws->on('close', function ($ws, $fd) { echo "client-{$fd} is closed "; }); $ws->start();
5、MQTT服务器
<?php function decodeValue($data) { return 256 * ord($data[0]) + ord($data[1]); } function decodeString($data) { $length = decodeValue($data); return substr($data, 2, $length); } function mqttGetHeader($data) { $byte = ord($data[0]); $header['type'] = ($byte & 0xF0) >> 4; $header['dup'] = ($byte & 0x08) >> 3; $header['qos'] = ($byte & 0x06) >> 1; $header['retain'] = $byte & 0x01; return $header; } function eventConnect($header, $data) { $connect_info['protocol_name'] = decodeString($data); $offset = strlen($connect_info['protocol_name']) + 2; $connect_info['version'] = ord(substr($data, $offset, 1)); $offset += 1; $byte = ord($data[$offset]); $connect_info['willRetain'] = ($byte & 0x20 == 0x20); $connect_info['willQos'] = ($byte & 0x18 >> 3); $connect_info['willFlag'] = ($byte & 0x04 == 0x04); $connect_info['cleanStart'] = ($byte & 0x02 == 0x02); $offset += 1; $connect_info['keepalive'] = decodeValue(substr($data, $offset, 2)); $offset += 2; $connect_info['clientId'] = decodeString(substr($data, $offset)); return $connect_info; } $server = new SwooleServer("127.0.0.1", 9501, SWOOLE_BASE); $server->set([ 'open_mqtt_protocol' => 1, // 启用 mqtt 协议 'worker_num' => 1, ]); $server->on('connect', function ($server, $fd) { echo "Client:Connect. "; }); $server->on('receive', function ($server, $fd, $from_id, $data) { $header = mqttGetHeader($data); var_dump($header); if ($header['type'] == 1) { $resp = chr(32) . chr(2) . chr(0) . chr(0); eventConnect($header, substr($data, 2)); $server->send($fd, $resp); } elseif ($header['type'] == 3) { $offset = 2; $topic = decodeString(substr($data, $offset)); $offset += strlen($topic) + 2; $msg = substr($data, $offset); echo "client msg: $topic ---------- $msg "; //file_put_contents(__DIR__.'/data.log', $data); } echo "received length=" . strlen($data) . " "; }); $server->on('close', function ($server, $fd) { echo "Client: Close. "; }); $server->start();