page contents

基于Swoole如何搭建TCP服务

通过Swoole如何搭建TCP服务? 通过Swoole如何搭建TCP客户端? 通过Swoole搭建的TCP服务,更深入理解Swoole的事件驱动模式

attachments-2020-09-irPD0fEw5f59798e16f9e.png


本节将会讲解以下3个问题:

通过Swoole如何搭建TCP服务?

通过Swoole如何搭建TCP客户端?

通过Swoole搭建的TCP服务,更深入理解Swoole的事件驱动模式


通过Swoole可以快速创建一个TCP服务,新建一个文件命名为 tcp_server.php,代码如下:

attachments-2020-09-A4BtBwSt5f597ecf90500.jpg

在命令行执行如下命令就可以开启TCP服务:

php tcp_server.php

运行完命令后就可以通过 netstat 工具查看服务是否启动成功,如果已经在监听9501端口了,这时就可以使用 telnet/netcat 工具来连接服务器了。

telnet 127.0.0.1 9501

helloServer: hello

netstat工具使用方法:netstat -an | grep 9501

代码逻辑分析:

通过以上代码就可以创建一个TCP服务,监听的端口是9501。它的逻辑很简单,当客户端$socket通过网络发送一个hello字符串时,服务器端会回复一个Server:hello字符串。

Server是异步服务器,所以是同过监听事件的方式来编写程序的。当对应的事件发生时,底层会主动回调指定的函数。如当有洗的TCP连接金额入时,会执行 onConnect 事件回调,当某个连接向服务器发送数据时会回调 onReceive 函数。

注意事项:

服务器可以同时被成千上万个客户端连接,$fd 就是客户端连接的唯一标识符

Receive 事件的回调函数中 $from_id 为线程ID

调用 $srver->send() 方法向客户端连接发送数据,参数就是 $fd 柯达护短标识符

调用 $server->close() 方法可以强制关闭某个客户端连接

客户端可能会主动断开连接,此时会触发 onClose 事件回调

无法连接到服务器的简单检测手段:

在linux下,使用 netstat -an | grep 端口,查看端口是否已经被打开处于Listening状态

上一步确认后,再检查防火墙问题

注意服务器所用的IP地址,如果是127.0.0.1回环地址,则客户端只能使用127.0.0.1才能连接上

用的阿里云服务器或者腾讯云服务器,需要再安全权限组进行设置开发的端口

TCP服务已经启动,下面我们要用Swoole搭建TCP客户端来连接TCP服务。新建一个文件,命名为 tcp_client.php,代码如下:

attachments-2020-09-0mhOJPJL5f597f0ccbae7.jpg

上面代码创建了一个TCP的同步客户端,此客户端用于连接 server.php 开启的TCP服务。向服务端发送一个 hello world 字符串,服务器会返回一个 Server:hello world 字符串。

在命令行运行如下命令就可以连接TCP服务:

php tcp_client.php

Server:hello world

这个客户端是同步阻塞的,connect/send/recv 会等待IO完成后再返回。同步阻塞操作并不消耗CPU资源。当IO操作未完成时,当前进程会自动转入 sleep 模式。当IO完成后,操作系统会唤醒当前进程,继续向下执行代码。

流程如下:

TCP需要进行3次握手,所以connect至少需要3次网络传输过程

在发送少量数据时,$client->send 都是可以立即返回的。发送大量数据时,socket 缓冲区可能会塞满,send 操作会阻塞。

recv 操作会阻塞等待服务器返回数据,recv 耗时等于服务器处理时间+网络传输耗时之和。

TCP客户端还有一种异步非阻塞的实现形式。使用异步模式时,connect 会理解返回 true。但实际上连接并未建立。这时不能在 connect 后立即使用 send 发送数据,需要先通过isConnected() 判断是否连接成功。当连接成功后,系统会自动回调 onConnect 函数。这时才可以使用 send 函数向服务器发送数据。

通过上面的代码我们就实现了TCP服务端和客户端,当服务端和客户端建立TCP连接后,如何维持连接不断开呢?下面我们将介绍一下基于Swoole搭建的TCP服务器心跳维持方案。

正常情况下客户端中断TCP连接时,会发送一个FIN包,进行4次断开握手来通知服务器。但一些异常情况下,如客户端突然断电断网或者网络异常,服务器可能无法得知客户端已断开连接。尤其是异动网络,TCP连接非常不稳定,所以需要一套机制来保证服务器和客户端之间的连接的有效性。

Swoole扩展本身内置了这种机制,开发者只需要配置一个参数即可启用。Swool在每次收到客户端数据会记录一个时间戳,当客户端在一定时间内未向服务器端发送数据,那服务器会自动切断连接。

配置方法如下:

attachments-2020-09-4cUffQUQ5f597f3140b1b.jpg

上面的设置就是每5秒侦测一次心跳,一个TCP连接如果再10秒内未向服务器发送数据,连接将会被切断。

通过以上案例我们对Swoole的事件驱动模型有了一定的了解。下面我们将详细介绍Swoole的回调事件。

事件执行顺序

所有事件回调均在 $server->start 后发生

服务器关闭程序终止时最后一次事件是 onShutdown

服务器启动成功后,onStart /onManagerStart / onWorkerStart 会在不同的进程内并发执行

onReceive / onConnect / onClose 在 Worker 进程中触发

Worker / Task 进程启动/结束时会分别调用一次 onWorkerStart / onWorkerStop

onTask 事件仅在 task 进程中发生onFinish 事件仅在 Worker进程中发生

事件函数介绍

onStart

onShutdown

onWorkerStart

onWorkerStop

onWorkerExit

onConnect

onReceive

onPacket

onClose

onTask

onFinish

onPipeMessage

onWorkerError

onManagerStart

onManagerStop


attachments-2020-09-QVzpTtYd5f597e99709fe.jpg

  • 发表于 2020-09-10 09:17
  • 阅读 ( 511 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章