服务端框架

更新时间:
2024-01-30
下载文档

服务端框架

本节介绍 VSOA 服务端框架的开发流程、步骤和注意事项。

开发流程

创建服务端时,不同的开发语言在流程上略有区别,但总体都是按照如下步骤进行:

开发步骤

步骤 1:创建服务端

创建 VSOA 微服务时,每个微服务都需要有一个确定的端口与确定的微服务名。创建服务端时若需要设定密码,则可以通过对应的接口或参数指定该服务的通信密码。

说明:
在使用 C 语言开发方式中,微服务名以 JSON 的格式给出,则必须包含 name 字段。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "vsoa_server.h"

#define MY_SERVER_PASSWD "123456"

static vsoa_server_t *server;

int main (int argc, char **argv)
{
    struct sockaddr_in addr;

    bzero(&addr, sizeof(struct sockaddr_in));
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(3001);
    addr.sin_addr.s_addr = INADDR_ANY;

#ifdef VSOA_HAS_SIN_LEN
    addr.sin_len = sizeof(struct sockaddr_in);
#endif

    /*
    * Initialize server
    */
    server = vsoa_server_create("{\"name\":\"light_server\"}");
    if (!server) {
        fprintf(stderr, "Can not create VSOA server!\n");
        return  (-1);
    }

    /*
    * If need password
    */
    vsoa_server_passwd(server, MY_SERVER_PASSWD);

    return (0);
}
var vsoa = require('vsoa');

/*
 * Create server
 */
var server = new vsoa.Server({
    info: {
        name: 'light_server'
    }, passwd: '123456'
});
import java.net.InetSocketAddress;
import com.acoinfo.vsoa.*;

public class light_server {
    private  static String  SERVER_NAME   = "light_server";
    private  static String  SERVER_INFO   = "\"java language VSOA server\"";
    private  static String  PASSWORD      = "123456";
    private  static String  SERVER_ADDR   = "0.0.0.0";
    private  static int     SERVER_PORT   = 3001;

    static Server server;

    public static void main(String[] args) {

        /*
        * Initialize server
        */
        try {
            ServerOption opt = new ServerOption(SERVER_INFO, PASSWORD, false);
            InetSocketAddress address = new InetSocketAddress(SERVER_ADDR, SERVER_PORT);
            server = new Server(opt) {
                @Override
                public void onClient(CliHandle client, boolean link) {
                    if (!client.isConnected()) {
                        System.out.println("disconnected");
                    }

                    System.out.println("Client link " + link + " address: " + client.address().toString());
                }
            };
        } catch (Exception e1) {
            e1.printStackTrace();
            return ;
        }
    }
}
package main

import (
    "gitee.com/sylixos/go-vsoa/server"
)

func ServerTest() {
    serverOption := server.Option{
        Password: "123456",
    }
    /*
    * Create a new server instance
    */
    s := server.NewServer("light_server", serverOption)
}

func main() {
    ServerTest()
}

步骤 2:启动微服务

微服务创建成功后,需要启动微服务。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "vsoa_server.h"

#define MY_SERVER_PASSWD "123456"

static vsoa_server_t *server;

int main (int argc, char **argv)
{
    struct sockaddr_in addr;

    bzero(&addr, sizeof(struct sockaddr_in));
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(3001);
    addr.sin_addr.s_addr = INADDR_ANY;

#ifdef VSOA_HAS_SIN_LEN
    addr.sin_len = sizeof(struct sockaddr_in);
#endif

    /*
    * Initialize server
    */
    server = vsoa_server_create("{\"name\":\"light_server\"}");
    if (!server) {
        fprintf(stderr, "Can not create VSOA server!\n");
        return  (-1);
    }

    /*
    * If need password
    */
    vsoa_server_passwd(server, MY_SERVER_PASSWD);

    /*
    * Start server
    */
    if (!vsoa_server_start(server, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) {
        vsoa_server_close(server);
        fprintf(stderr, "Can not start VSOA server!\n");
        return  (-1);
    }

    return (0);
}
var vsoa = require('vsoa');
var socket = require('socket');

/*
 * Create server
 */
var server = new vsoa.Server({
    info: {
        name: 'light_server'
    }, passwd: '123456'
});

/*
 * Server start
 */
server.start({
    domain: socket.AF_INET, addr: '0.0.0.0', port: 3001
});
import java.net.InetSocketAddress;
import com.acoinfo.vsoa.*;

public class light_server {
    private  static String  SERVER_NAME   = "light_server";
    private  static String  SERVER_INFO   = "\"java language VSOA server\"";
    private  static String  PASSWORD      = "123456";
    private  static String  SERVER_ADDR   = "0.0.0.0";
    private  static int     SERVER_PORT   = 3001;

    static Server server;

    public static void main(String[] args) {

        /*
        * Initialize server
        */
        try {
            ServerOption opt = new ServerOption(SERVER_INFO, PASSWORD, false);
            InetSocketAddress address = new InetSocketAddress(SERVER_ADDR, SERVER_PORT);
            server = new Server(opt) {
                @Override
                public void onClient(CliHandle client, boolean link) {
                    if (!client.isConnected()) {
                        System.out.println("disconnected");
                    }

                    System.out.println("Client link " + link + " address: " + client.address().toString());
                }
            };

            /*
            * Start server
            */
            if (!server.start(address, null)) {
                return;
            }
        } catch (Exception e1) {
            e1.printStackTrace();
            return ;
        }
    }
}
package main

import (
    "gitee.com/sylixos/go-vsoa/server"
)

func ServerTest() {
    serverOption := server.Option{
        Password: "123456",
    }
    /*
    * Create a new server instance
    */
    s := server.NewServer("light_server", serverOption)

    s.Serve("localhost:3001")
}

func main() {
    ServerTest()
}

说明:
在 Node.js 的环境中,socket.AF_INET 应为 vsoa.AF_INET,详情可见 https://www.npmjs.com/package/vsoa 。

步骤 3:监听事件或循环

VSOA 微服务在启动成功之后,它应当始终监听所有的 VSOA 输入事件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "vsoa_server.h"

#define MY_SERVER_PASSWD "123456"

static vsoa_server_t *server;

int main (int argc, char **argv)
{
    int cnt, max_fd;
    fd_set fds;
    struct sockaddr_in addr;
    struct timespec timeout = { 1, 0 };

    bzero(&addr, sizeof(struct sockaddr_in));
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(3001);
    addr.sin_addr.s_addr = INADDR_ANY;

#ifdef VSOA_HAS_SIN_LEN
    addr.sin_len = sizeof(struct sockaddr_in);
#endif

    /*
    * Initialize server
    */
    server = vsoa_server_create("{\"name\":\"light_server\"}");
    if (!server) {
        fprintf(stderr, "Can not create VSOA server!\n");
        return  (-1);
    }

    /*
    * If need password
    */
    vsoa_server_passwd(server, MY_SERVER_PASSWD);

    /*
    * Start server
    */
    if (!vsoa_server_start(server, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) {
        vsoa_server_close(server);
        fprintf(stderr, "Can not start VSOA server!\n");
        return  (-1);
    }

    while (1) {
        FD_ZERO(&fds);
        max_fd = vsoa_server_fds(server, &fds);

        cnt = pselect(max_fd + 1, &fds, NULL, NULL, &timeout, NULL);
        if (cnt > 0) {
            vsoa_server_input_fds(server, &fds);
        }
    }

    return (0);
}
var vsoa = require('vsoa');
var socket = require('socket');

/*
 * Create server
 */
var server = new vsoa.Server({
    info: {
        name: 'light_server'
    }, passwd: '123456'
});

/*
 * Client event
 */
server.onclient = function(client, link) {
    console.log(`Client link ${link} address: ${client.address().addr}`);
    if (link) {
        client.setKeepAlive(5000);
    }
};

/*
 * Server start
 */
server.start({
    domain: socket.AF_INET, addr: '0.0.0.0', port: 3001
});

/*
 * Event loop
 */
require('iosched').forever();
import java.net.InetSocketAddress;
import com.acoinfo.vsoa.*;

public class light_server {
    private  static String  SERVER_NAME   = "light_server";
    private  static String  SERVER_INFO   = "\"java language VSOA server\"";
    private  static String  PASSWORD      = "123456";
    private  static String  SERVER_ADDR   = "0.0.0.0";
    private  static int     SERVER_PORT   = 3001;

    static Server server;

    public static void main(String[] args) {

        /*
        * Initialize server
        */
        try {
            ServerOption opt = new ServerOption(SERVER_INFO, PASSWORD, false);
            InetSocketAddress address = new InetSocketAddress(SERVER_ADDR, SERVER_PORT);
            server = new Server(opt) {
                @Override
                public void onClient(CliHandle client, boolean link) {
                    if (!client.isConnected()) {
                        System.out.println("disconnected");
                    }

                    System.out.println("Client link " + link + " address: " + client.address().toString());
                }
            };

            /*
            * Start server
            */
            if (!server.start(address, null)) {
                return;
            }
        } catch (Exception e1) {
            e1.printStackTrace();
            return ;
        }

        while(true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
package main

import (
    "time"

    "gitee.com/sylixos/go-vsoa/server"
)

func ServerTest() {
    serverOption := server.Option{
        Password: "123456",
    }
    /*
    * Create a new server instance
    */
    s := server.NewServer("light_server", serverOption)

    go func() {
        _ = s.Serve("localhost:3001")
    }()
}

func main() {
    ServerTest()

    for {
        time.Sleep(1 * time.Second)
    }
}

说明:

  • 在 Node.js 的环境中,不需要事件循环,即删除 require('iosched').forever();
  • 在 Node.js 的环境中,socket.AF_INET 应为 vsoa.AF_INET,详情可见 https://www.npmjs.com/package/vsoa 。

注意事项

C/C++ 服务端编译时需链接如下表所示的 VSOA 动态库,在 RealEvo-IDE 中配置时请参考 C/C++ 开发示例,Linux 下开发请参考 搭建 Linux 运行环境 提供的 C 语言范例进行配置。

库名称功能
libvsoa-json.so提供 JSON 功能
libvsoa-server.so提供服务端功能
libvsoa-parser.so提供参数解析功能
文档内容是否对您有所帮助?
有帮助
没帮助