使用swoole搭建socket长连接

Swoole简介

通常基于php扩展使用纯PHP就可以完全实现异步网络服务器和客户端程序。但是想实现一个类似于多IO线程,还是有很多繁琐的编程工作要做,包括如何来管理连接,如何来保证数据的收发原则性,网络协议的处理。
开源项目Swoole使用C语言和PHP结合来完成了这项工作。灵活多变的业务模块使用PHP开发效率高,基础的底层和协议处理部分用C语言实现,保证了高性能。它以扩展的方式加载到了PHP中,提供了一个完整的网络通信的框架,然后PHP的代码去写一些业务。它的模型是基于多线程Reactor+多进程Worker,既支持全异步,也支持半异步半同步。

Swoole的特点

  • Accept线程,解决Accept性能瓶颈和惊群问题
  • 多IO线程,可以更好地利用多核
  • 提供了全异步和半同步半异步2种模式
  • 处理高并发IO的部分用异步模式
  • 复杂的业务逻辑部分用同步模式
  • 底层支持了遍历所有连接、互发数据、自动合并拆分数据包、数据发送原子性。

为何选择Swoole及Swoole性能

包括腾讯企业QQ、聚美优品等众多公司的大规模部署和实践。
我在网站挂载的服务器上做了测试,由于服务器配置可能不高,仅能支持2万并发。具体性能还有待调整提高。

简单部署

选择了8000端口作为socket连接端口,其中server.php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 8000);

//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
var_dump($request->fd, $request->get, $request->server);
$ws->push($request->fd, "hello, welcome\n");
});

//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
echo "Message: {$frame->data}\n";
$ws->push($frame->fd, "server: {$frame->data},this is yatesun");
});

//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});

$ws->start();

执行php server.php,启动swoole服务,监听8000端口,可以在系统中查看到端口已经监听成功,接下来可以通过chrome中的Console,执行js代码,来测试服务是否正常运行。

JS调试

1
2
3
4
5
6
7
var exampleSocket = new WebSocket("ws://119.29.182.88:8000");
exampleSocket.onopen = function (event) {
exampleSocket.send("亲爱的服务器!我连上你啦!");
};
exampleSocket.onmessage = function (event) {
console.log(event.data);
};

接下来执行下面代码,则能收到服务器返回的信息:

1
exampleSocket.send("爱你哦");

server: 爱你哦,this is yatesun