我们新建一个 tcp.php
文件:
//创建Server对象, 监听 10.0.2.7:81 端口
$server = new Swoole\Server('10.0.2.7', 81);
$server->on('Start', function($server){
echo 'Swoole TCP server started at '.date('Y-m-d H:i:s').PHP_EOL;
});
//监听连接进入事件
$server->on('Connect', function($server, $fd){
//$fd: 客户端连接的唯一标识, int
echo date('Y-m-d H:i:s').' Client connected fd='.$fd.PHP_EOL;//在服务器命令行端显示文字
$server->send($fd, 'Welcome, your ID is: '.$fd.PHP_EOL);
});
//监听数据接收事件
$server->on('Receive', function($server, $fd, $reactor_id, $data){
//$reactor_id: TCP连接所在的Reactor线程ID, int
//$data: 收到的数据内容,可能是文本或者二进制内容
echo date('Y-m-d H:i:s').' Client '.$fd.' send message: '.trim($data).PHP_EOL;
$server->send($fd, "Server: {$data}");
//如果收到 quit 则关闭连接
if(trim($data) == 'quit'){
echo 'Client '.$fd.' typed [quit] to close the connection'.PHP_EOL;
$server->close($fd);
}
});
//监听连接关闭事件
$server->on('Close', function($server, $fd){
echo date('Y-m-d H:i:s').' Client closed: fd='.$fd.PHP_EOL;
});
//启动服务
$server->start();
这样就创建了一个 TCP
服务器,监听本机 81
端口。
Server
是异步服务器,所以是通过监听事件的方式来编写程序的。当对应的事件发生时底层会主动回调指定的函数。如当有新的 TCP
连接进入时会执行 onConnect
事件回调,当某个连接向服务器发送数据时会回调 onReceive
函数。
- 服务器可以同时被成千上万个客户端连接,
$fd
就是客户端连接的唯一标识符, 这里是int
类型 - 调用
$server->send($fd, $msg)
方法向客户端连接发送数据,参数就是$fd
客户端标识符 - 调用
$server->close($fd)
方法可以强制关闭某个客户端连接 - 客户端可能会主动断开连接,此时会触发
onClose
事件回调
上面的代码实现了这样一个简单的业务逻辑:
-
当客户端
Socket
登录时, 服务端显示用户的连接时间及id, 并给客户端发恢复欢迎信息及用户标识id. -
当发送字符串, 比如
hello
时,服务端会显示何时收到哪个用户的什么信息, 并给客户端回复一个Server: hello
字符串。 -
如果用户发送了字符串
quit
, 则表示用户要断开连接.
服务端信息截图:
客户端操作使用telnet
, 截图如下: