C++开发者如何使用Swoole

PHP编写的Server程序在某些情况下表现会较差

  • 内存占用敏感的场景,PHP底层使用内存结构zval来管理所有变量,会额外占用内存,如一个int32的整数可能需要占用16(PHP7)或24字节(PHP5)的内存,而C/C++只需要4字节。如果系统需要存储大量整数,占用的内存会非常大。
  • PHP是动态解释执行的,计算性能较差,纯运算的代码可能会比C/C++程序差几十甚至上百倍。此类场景下不适合使用PHP

C/C++的支持弥补了这些不足,在上述场景下可以使用c-swoole或者cpp-swoole来编写Server程序。

cpp-swoole是对c-swoole的面向对象封装,支持了绝大部分swoole_server的特性包括task功能,另外还支持高精度定时器特性。

cpp-swoole依赖libswoole.so,需要先编译c-swoole生成libswoole.so

编译libswoole.so

git clone https://github.com/swoole/swoole-src.git
phpize
./configure
cmake .
#cmake -DCMAKE_INSTALL_PREFIX=/opt/swoole .
sudo make install

编译安装好libswoole.so后就可以下载cpp-swoole源码,编译libswoole_cpp.so

编译libswoole_cpp.so

git clone https://github.com/swoole/cpp-swoole.git
cmake .
make
sudo make install

编写程序

头文件:

#include <swoole/Server.hpp>
#include <swoole/Timer.hpp>

服务器程序只需要继承swoole::Server,并实现响应的回调函数即可。

#include <swoole/Server.hpp>
#include <swoole/Timer.hpp>
#include <iostream>

using namespace std;
using namespace swoole;

class MyServer : public Server
{
public:
    MyServer(string _host, int _port, int _mode = SW_MODE_PROCESS, int _type = SW_SOCK_TCP) :
            Server(_host, _port, _mode, _type)
    {
        serv.worker_num = 4;
        SwooleG.task_worker_num = 2;
    }

    virtual void onStart();
    virtual void onShutdown() {};
    virtual void onWorkerStart(int worker_id) {}
    virtual void onWorkerStop(int worker_id) {}
    virtual void onPipeMessage(int src_worker_id, const DataBuffer &) {}
    virtual void onReceive(int fd, const DataBuffer &data);
    virtual void onConnect(int fd);
    virtual void onClose(int fd);
    virtual void onPacket(const DataBuffer &data, ClientInfo &clientInfo) {};

    virtual void onTask(int task_id, int src_worker_id, const DataBuffer &data);
    virtual void onFinish(int task_id, const DataBuffer &data);
};

void MyServer::onReceive(int fd, const DataBuffer &data)
{
    swConnection *conn = swWorker_get_connection(&this->serv, fd);
    printf("onReceive: fd=%d, ip=%s|port=%d Data=%s|Len=%ld\n", fd, swConnection_get_ip(conn),
           swConnection_get_port(conn), (char *) data.buffer, data.length);

    int ret;
    char resp_data[SW_BUFFER_SIZE];
    int n = snprintf(resp_data, SW_BUFFER_SIZE, (char *) "Server: %*s\n", (int) data.length, (char *) data.buffer);
    ret = this->send(fd, resp_data, (uint32_t) n);
    if (ret < 0)
    {
        printf("send to client fail. errno=%d\n", errno);
    }
    else
    {
        printf("send %d bytes to client success. data=%s\n", n, resp_data);
    }
    DataBuffer task_data("hello world\n");
    this->task(task_data);
//    this->close(fd);
}

void MyServer::onConnect(int fd)
{
    printf("PID=%d\tConnect fd=%d\n", getpid(), fd);
}

void MyServer::onClose(int fd)
{
    printf("PID=%d\tClose fd=%d\n", getpid(), fd);
}

void MyServer::onTask(int task_id, int src_worker_id, const DataBuffer &data)
{
    printf("PID=%d\tTaskID=%d\n", getpid(), task_id);
}

void MyServer::onFinish(int task_id, const DataBuffer &data)
{
    printf("PID=%d\tClose fd=%d\n", getpid(), task_id);
}

void MyServer::onStart()
{
    printf("server start\n");
}

class MyTimer : Timer
{
public:
    MyTimer(long ms, bool interval) :
            Timer(ms, interval)
    {

    }

    MyTimer(long ms) :
            Timer(ms)
    {

    }

protected:
    virtual void callback(void);
    int count = 0;
};

void MyTimer::callback()
{
    printf("#%d\thello world\n", count);
    if (count > 9)
    {
        this->clear();
    }
    count++;
}

int main(int argc, char **argv)
{
    MyServer server("127.0.0.1", 9501, SW_MODE_SINGLE);
    server.listen("127.0.0.1", 9502, SW_SOCK_UDP);
    server.listen("::1", 9503, SW_SOCK_TCP6);
    server.listen("::1", 9504, SW_SOCK_UDP6);
    server.setEvents(EVENT_onStart | EVENT_onReceive | EVENT_onClose | EVENT_onTask | EVENT_onFinish);
    server.start();
}

  • 傻大猫

    编译 gcc -std=c++11 -lstdc++ -o server server.cpp -lswoole_cpp -lswoole

  • 傻大猫

    需要升级gcc到4.8版以上

  • xhc

    macos 下不能编译。

  • 消失的NPC

    你好,请问一下我在编译生成libswoole.so的过程中有报错,home/chen/swoole-src-2.0.7/lib/libswoole.so: undefined reference to `coro_handle_timeout' collect2: error: ld returned 1 exit status make[2]: *** [bin/test_server] Error 1 make[1]: *** [CMakeFiles/test_server.dir/all] Error 2 make: *** [all] Error 2 请问这是什么原因导致的呢?

  • 消失的NPC

    编译生成php swoole扩展没有问题,想编译生成libswoole.so用于c++使用swoole的过程中出现错误。

  • @消失的NPC swoole有些版本是不可以编译的,你切到 v1.9.10 或 v1.9.18,就可以编译了