Swoole 簡單學習(2)

Swoole 簡單學習(2)


 

swoole之tcp服務器:html

//建立tcp服務器
new swoole_server(string $host,int $port,int $mode=SWOOLE_PROCESS,int $sock_type=SWOOLE_SOCK_TCP);前端

//事件
bool swoole_server->on(string $event,mixed $callback);mysql

//開啓tcp服務器
bool swoole_server->start();react

//發送數據
bool swoole_server->send(int $fd,string $data,int $reactorThreadld=0);jquery

function swoole_server->set(array $setting);linux

參數說明:
//$host的值:內網127.0.0.一、外網ip、0.0.0.0、ipv4或ipv6。
//$port端口:1024如下須要root權限,習慣用9501。
//$mode:默認SWOOLE_PROCESS多進程方式。
//$socl_type:默認SWOOLE_SOCK_TCP。web

//$event:
connect創建連接時(回調函數有2個參數:$serv服務器信息、$fd客戶端信息);
receive接收到數據(回調函數有4個參數:$serv服務器信息、$fd客戶端信息、$from_id客戶端id、$data接收的數據);
close關閉鏈接(回調函數有2個參數:$serv服務器信息、$fd客戶端信息);sql

可使用網絡調式助手軟件、要關閉服務器防火牆。
=========================================================================
swoole之udp服務器:json

//建立UDP服務器,和建立tcp服務器最後一個參數不同。
new swoole_server(string $host,int $port,int $mode=SWOOLE_PROCESS,int $sock_type=SWOOLE_SOCK_UDP);數組

//接收到數據
bool swoole_server->on(string $event,mixed $callback);
$event:'packet',接收數據

//發送數據
bool swoole_server->sendto(string $ip,int $port,string $data,int $server_socket=-1);


示例:
//建立服務
$serv = new swoole_server("0.0.0.0",9502,SWOOLE_PROCESS,SWOOLE_SOCK_UDP);
//監聽接收數據
$serv->on('packet',function($serv,$data,$fd){
//發送回去數據
$serv->sendto($fd['address'],$fd['port'],"收到數據:$data");
});
//啓動服務
$serv->start();
=======================================================================================
swoole之web服務器

new swoole_http_server();
swoole_http_Server 繼承來自swoole_server.
參數1:string $host 監聽ip地址
參數2:int $port 監聽的端口
on/start函數。

示例:
$serv = new swoole_http_server("0.0.0.0",9501);
//獲取請求
$serv->on('request',function($request,$response){
  $response->header("Content-Type","text/html;charset=utf-8");//設置返回頭
  $response->end("hello".json_encode($request));
});
$serv->start();

在瀏覽器測試:xxx.xxx.xxx.xxx:9501。
======================================================================================
swoole之WebSocket服務器

new swoole_websocket_server();
swoole_websocket_server 繼承自swoole_http_server;
on/start函數;
open/message/close;//on函數的事件參數
push()發送數據。


示例:

//服務端
$serv = new swoole_websocket_server("0.0.0.0",9501);
$serv->on('open',function($serv,$client_info){
$serv->push($client_info->fd,"hello");
});
$serv->on('message',function($serv,$client_info){
echo "接收到客戶端消息:".$client_info;
$serv->push($client_info->fd,"收到消息");
});
$serv->on('close',function($serv,$client_info){
echo "close".$client_info;
});

$serv->start();

//前端websocket
<script>
var webSocketUrl = "ws://xxx.xxx.xxx.xxx:9501";
var webSocketServer = new WebSocket(webSocketUrl);
webSocketServer.onopen = function(event){
console.log('鏈接成功');
}
webSocketServer.onclose = function(event){
console.log('關閉');
}
webSocketServer.onmessage = function(event){
console.log(event.data);
}
webSocketServer.onerror = function(event,e){
console.log('錯誤');
}
</script>
============================================================================
swoole之定時器
js的setInterval()方法
linux的crontab

循環觸發函數:
swoole_timer_tick()
參數1:int $after_time_ms 指定時間【毫秒】
參數2:mixed $callback function 執行的函數
參數3:mixed $user_param 用戶參數

清除定時器函數:
bool swoole_timer_clear(int $timer_id).

單次觸發函數:
swoole_timer_after()
參數與循環觸發函數同樣。

示例:
循環執行
swoole_timer_tick(3000,function($timer_id){
echo $timer_id;
});

單次執行
swoole_timer_after(3000,function(){
echo '單次';
});
=================================================================================
swoole之異步TCP服務器

task()函數 //投遞異步任務
on('事件',function(){}) //異步執行的事件函數
finish()函數 //任務處理完成後結果

示例:
$serv = new swoole_server("0.0.0.0",9501);
//設置異步,進程工做數
$serv->set(array('task_worker_num'=>4));
//投遞異步任務
$serv->on("receive",function($serv,$fd,$from_id,$data){
$task_id = $serv->task($data);//異步ID
echo "異步ID:".$task_id;
});

//處理異步任務
$serv->on('task',function($serv,$task_id,$from_id,$data){
echo "異步ID:".$task_id;
$serv->finish("$data ok");
});

//處理結果
$serv->on('finish',function($serv,$task_id,$data){
echo "執行成功";
});

$serv->start();
===========================================================================
swoole之tcp客戶端

new swoole_client();

示例:
//建立客戶端
$client = new swoole_client(SWOOLE_SOCK_TCP);
//鏈接服務器
$client->connect('xxx.xxx.xxxx.xxx',9501,5) or die('鏈接失敗');
//發送數據
$client->send('hello') or die('發送失敗');
//接收數據
$data = $client->recv();
//關閉客戶端
$client->close();
=======================================================================================
swoole之tcp異步客戶端

new swoole_client()
SWOOLE_SOCK_TCP //TCP協議
SWOOLE_SOCK_ASYNC //異步支持

示例:
$client = new swoole_client(SWOOLE_SOCK_TCP,SWOOLE_SOCK_ASYNC);
//註冊鏈接成功的回調
$client->on('connect',function($cli){
$cli->send('hello');
});
//註冊數據接收
$client->on('receive',function($cli,$data){
echo $data;
});
//註冊鏈接失敗
$client->on('error',function($cli){
echo '失敗';
});
//註冊關閉
$client->on('close',function($cli){
echo '關閉';
});
//發起鏈接
$client->connect('xxx.xxx.xxx.xxx',9501,10);
==============================================================================
swoole之進程

new swoole_process().
參數1:mixed $function 子進程建立成功後執行的函數。
參數2:$redirect_stdin_stdout 重定向子進程的標準輸入輸出。啓動此選項後,在進程
內echo將不是打印到屏幕,而是寫入到管道。讀取鍵盤輸入將變成從管道中讀取
,默認爲阻塞讀取。
參數3:$create_pipe 是否建立管道,
$redirect_stdin_stdout後,此選項將忽略用戶參數,強制爲true,若是子進程內沒有
進程間通訊,能夠設置爲false。

示例:
//進程調用的執行函數
function doProcess(swoole_process $worker){
echo "PID".$worker_pid;
}

//建立進程
$process = new swoole_process("doProcess");
$pid = $process->start();
//建立第二個進程
$process = new swoole_process("doProcess");
$pid = $process->start();
//建立第三個進程
$process = new swoole_process("doProcess");
$pid = $process->start();

//等待結束
swoole_process::wait();
=============================================================================
swoole進程事件:
swoole_event_add();
參數1:int $sock
int 文件描述符
mixed $read_callback 就是stream_socket_client/fsockopen 建立的資源
sockets資源,就是sockets擴展中socket_create建立的資源,須要在編譯時
加入.configure --enable-sockets
參數2:可讀回調函數

示例:

//進程調用的執行函數
function doProcess(swoole_process $worker){
$process->write('pid'.$worker->pid);//子進程寫入管道pipe
echo "寫入信息:¥worker->pid $worker->callback";
}

$workers = [];//進程池
$worker_num = 3;//進程數量
for($i=0;$i<$worker_num;$i++){
$process = new swoole_process('doProcess');//建立新進程
$pid = $process->start();//啓動進程並獲取進程id
$workers[$pid] = $process;//放入數組
}

//添加進程事件,向每個子進程添加須要執行的動做
foreach($workers as $process){
//添加
swoole_event_add($process->pipe,function($pipe) use($process){
$data = $process->read();
echo '接收到'.$data;
})
}
=============================================================================
swoole進程隊列通訊

string swoole_process->pop(int $maxsize=8192);//取數據
bool swoole_process->push(string $data);//放數據
array swoole_process::wait(bool $blocking=true);

示例:
$workers = [];//進程倉庫
$worker_num = 2;//最大進程數
for($i=0;$i<$worker_num;$i++){
$process = new swoole_process('doProcess',false,false);//建立新進程
$process->useQueue();//開啓隊列,相似於全局函數
$pid = $process->start();//啓動進程並獲取進程id
$workers[$pid] = $process;//放入數組
}

//進程調用的執行函數
function doProcess(swoole_process $worker){
$recv = $process->pop();//默認8192
echo "從主進程獲取導數據:$recv";
sleep(5);
$process->exit(0);
}
//主進程向子進程添加數據
foreach($workers as $pid=>$process){
$process->push("hello 子進程 $pid");
}
//等待子進程結束,回收資源
for($i=0;$i<$worker_num;$i++){
$ret = swoole_process::wait();//等待執行完成
$pid = $ret['pid'];
unset($workers[$pid]);
echo "子進程$pid退出";
}
===============================================================================
進程信號觸發器
bool swoole_process::signal(int $signo,callable $callback);

function swoole_process::alarm(int $interval_usec,int $type=ITIMER_REAL):bool.

示例:
//觸發函數,異步執行的,
swoole_process::signal(SIGALRM,function(){
echo '123';
});

//定時信號
swoole_process::alarm(100*1000);//100毫秒後執行

//若是達到10次中止
swoole_process::signal(SIGALRM,function(){
static $i=0;
echo '123';
$i++;
if($i>10){
swoole_process::alarm(-1);//清除定時器
}
});
===============================================================================
swoole之鎖機制

$lock = new swoole_lock(SWOOLE_MUTEX);
參數:文件鎖、讀寫鎖、信號量、互斥鎖、自旋鎖。
lock();
unlock();

示例:
//建立鎖對象
$lock = new swoole_lock(SWOOLE_MUTEX);//互斥鎖
echo '建立互斥鎖';
$lock->lock();//開始鎖定 主進程
if(pcntl_fork() > 0){
sleep(1);
$lock->unlock();//解鎖
}else{
echo '子進程在等待鎖';
$lock->lock();//上鎖
echo "子進程獲取鎖";
$lock->unlock();//釋放鎖
exit('子進程退出');
}
echo '主進程釋放鎖';
unset($lock);
sleep(1);
echo "子進程退出";
================================================================================
swoole之DNS查詢

語法:
swoole_async_dns_lookup('域名地址',function($host,$ip));

示例:
swoole_async_dns_lookup('www.baidu.com',function($host,$ip){
echo 'host='.$host .' ip='.$ip;
});
================================================================================
swoole之異步文件讀取

語法:
函數方式:
swoole_async_readfile(string $filename,mixed $callback);
面向對象方式:
Swoole\Async::readFile(string $filename,mixed $callback);

示例:
swoole_async_readfile(__DIR__.'/1.txt',function($filename,$content){
echo $filename . ':'.$content;
});
===================================================================================
swoole之異步文件寫入
語法:
swoole_async_writefile(string $filename,string $fileContent,
callable $callback=null,int $flags=0);

參數一:文件的名字,必須有可寫權限;
參數二:要寫入的內容,最大4M;
參數三:寫入後的回調函數,可選;
參數四:寫入選項,可使用FILE_APPEND表示追加到文件末尾;


示例:
swoole_async_writefile(__DIR__.'/1.txt','hello',function($filename){
echo $filename;
},0);
==========================================================================================
swoole之異步事件
語法:
bool swoole_event_add(int $sock,mixed $read_callback,mixed $write_callback=null,int $flags=null);
示例:
$fp = stream_socket_client("tcp://www.qq.com:80",$error,$errstr,30);
fwrite($fp,"GET / HTTP/1.1\r\nHost:www.qq.com\r\n\r\n");
//添加異步事件
swoole_event_add($fp,function($fp){
$resp = fread($fp,8192);
var_dump($resp);
swoole_event_del($fp);
fclose($fp);
});

echo "這個是異步的";
==========================================================================================
swoole之異步mysql操做
語法:
swoole_mysql
connect
on
escape
query
示例:
$db = new swoole_mysql();
$config = [
'host' => '192.168.10.1',
'user' => 'root',
'password' => '123456',
'database' => 'mysql',
'charset' => 'utf8'
];
//鏈接數據
$db->connect($config,function($db,$result){
if($result === false){
var_dump($db->connect_errno,$db->connect_error);
die('失敗');
}
//成功
$sql = 'show tables';
$db->query($sql,function(swoole_mysql $db,$res){
if($res === false){
var_dump($db->error);
die('查詢失敗');
}else if($res === true){
var_dump($db->affected_rows,$db->insert_id);
}
var_dump($res);
$db->close();
});
});
=======================================================================================
swoole之聊天的簡單實現:
服務器端代碼:
//建立websocket服務器
$ws = new swoole_websocket_server("0.0.0.0",9502);
$ws->on('open',function($ws,$request){
echo '新用戶:'.$request->fd .'加入';
//設置用戶id,存入全局變量
$GLOBALS['fd'][$request->fd]['id'] = $request->fd;
$GLOBALS['fd'][$request->fd]['name'] = '匿名用戶';
});
$ws->on('message',function($ws,$request){
$msg = $GLOBALS['fd'][$request->fd]['name'].":".$request->data."\n";
if(strstr($request->data,"#name#")){
//用戶設置暱稱
$GLOBALS['fd'][$request->fd]['name'] = str_replace("#name#",'',$request->data);
}else{
//發送給每個客戶端
foreach($GLOBALS['fd'] as $val){
$ws->push($val['id'],$msg);
}
}
});
$ws->on('close',function(){
echo '客戶端斷開鏈接:'.$request;
unset($GLOBALS['fd'][$request]);
});

$ws->start();

客戶端:
引入jquery.js、webSocket.js。
var msg = document.getElementById('msg');
var wsSwever = 'ws://192.168.10.1:9502';
var websocket = new WebSocket(wsServer);
websocket.onopen = function(evt){
  //顯示登陸服務器成功
  //msg.innerHTML = websocket.readState;
  //websocket.readState屬性:
  //CONNECTING 0 The connection is not yet open.
  //OPEN 1 The connection is open and ready to communite.
  //CLOSEING 2 The connection is in the process of closing。
  //CLOSED 3 The connection is closed or couldn't be opened.
}

websocket.onmessage = function(evt){   msg.innerHTML += evt.data +'<br>';//不斷遞增的數據   console.log('從服務器獲取到的數據:'+evt.data);};//監聽鏈接關閉websocket.onclose = function(evt){   console.log('服務器拒絕');};//監聽鏈接錯誤信息websocket.onerror = function(evt){   console.log('錯誤:'.evt.data);}//發送信息function send_msg(){   var text = document.getElementById('text').value;//獲取數據   websocket.send(text);   document.getElementById('text').value = '';}//發送暱稱function send_name(){   var text = document.getElementById('text').value;//獲取數據   websocket.send("#name#"+text);//向服務器發送數據   document.getElementById('text').value = '';   var myTitle = document.getElementById("myTitle");   myTitle.innerHtml = "IM "+text;   alert("設置成功");}

相關文章
相關標籤/搜索