位置服务框架
本节内容介绍 VSOA 位置服务框架的开发须知、步骤和注意事项。
开发须知
位置服务只有在未运行 ECSM 时才需要,若当前环境下已存在 ECSM,开发者无需按照如下步骤创建位置服务。
操作步骤
创建位置服务时,不同的开发语言在流程上略有区别,但总体都是按照如下步骤进行:
步骤 1:创建位置服务
每个位置服务需要有一个确定的端口,创建 VSOA 位置服务时,需要将服务端的服务名与服务端的端口对应。
/*
* Application: position_demo
*/
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include "vsoa_position.h"
#include "vsoa_platform.h"
/* My position server */
static vsoa_position_server_t *pos_serv;
/*
* Query callback
*/
static void query (void *arg, int domain, const char *query_name, vsoa_position_response_t *response)
{
struct sockaddr_in res;
if (strcmp(query_name, "light_server") == 0) {
if (domain < 0 || domain == AF_INET) {
bzero(&res, sizeof(struct sockaddr_in));
res.sin_family = AF_INET;
res.sin_port = htons(3001);
res.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
res.sin_len = sizeof(struct sockaddr_in);
#endif
vsoa_position_server_response(pos_serv, response,
(struct sockaddr *)&res,
sizeof(struct sockaddr_in), false);
return;
}
} else if (strcmp(query_name, "axis_server") == 0) {
if (domain < 0 || domain == AF_INET) {
bzero(&res, sizeof(struct sockaddr_in));
res.sin_family = AF_INET;
res.sin_port = htons(3002);
res.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
res.sin_len = sizeof(struct sockaddr_in);
#endif
vsoa_position_server_response(pos_serv, response,
(struct sockaddr *)&res,
sizeof(struct sockaddr_in), false);
return;
}
}
vsoa_position_server_response(pos_serv, response, NULL, 0, false);
}
/*
* main function
*/
int main (int argc, char **argv)
{
struct sockaddr_in pos_addr;
bzero(&pos_addr, sizeof(struct sockaddr_in));
pos_addr.sin_family = AF_INET;
pos_addr.sin_port = htons(3000);
pos_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
pos_addr.sin_len = sizeof(struct sockaddr_in);
#endif
pos_serv = vsoa_position_server_create(query, NULL);
if (!pos_serv) {
fprintf(stderr, "Can not create VSOA position server!\n");
return (-1);
}
return (0);
}
/*
* position_demo.js
*/
var vsoa = require('vsoa');
var socket = require('socket');
/* Demo server address */
var servers = [
{
name: 'light_server',
domain: socket.AF_INET,
addr: '127.0.0.1',
port: 3001,
security: false
},
{
name: 'axis_server',
domain: socket.AF_INET,
addr: '127.0.0.1',
port: 3002,
security: false
}
];
/* Position server */
var position = new vsoa.Position(servers, {
domain: socket.AF_INET, addr: '127.0.0.1', port: 3000
});
/*
* position_demo.java
*/
import java.net.InetSocketAddress;
import com.acoinfo.vsoa.Constant;
import com.acoinfo.vsoa.Position;
import com.acoinfo.vsoa.Position.PositionItem;
public class position_test {
public static PositionItem servers[] = {
new PositionItem("light_server", Constant.AF_INET, "127.0.0.1", 3001, false),
new PositionItem("axis_server", Constant.AF_INET, "127.0.0.1", 3002, false)
};
static Position position;
public static void main(String[] args) {
position = new Position(servers, new InetSocketAddress("127.0.0.1", 3000));
}
}
package main
import (
"gitee.com/sylixos/go-vsoa/position"
)
func PositionTest() {
/*
*Create a new position list
*/
pl := position.NewPositionList()
/*
*Add new positions to the list
*/
pl.Add(*position.NewPosition("light_server", 1, "127.0.0.1", 3001, false))
pl.Add(*position.NewPosition("axis_server", 1, "127.0.0.1", 3002, false))
}
func main() {
PositionTest()
}
from vsoa import Position
# Demo server address
def onquery(search: dict, reply: callable):
if search['name'] == 'light_server':
reply({ 'addr': '127.0.0.1', 'port': 3001, 'domain': socket.AF_INET })
elif search['name'] == 'axis_server':
reply({ 'addr': '127.0.0.1', 'port': 3002, 'domain': socket.AF_INET })
else:
reply(None)
# Create a position server
position = Position(onquery)
说明:
在 Node.js 的环境中,socket.AF_INET
应为vsoa.AF_INET
,详情可见 https://www.npmjs.com/package/vsoa 。
步骤 2:启动位置服务
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include "vsoa_position.h"
#include "vsoa_platform.h"
/* My position server */
static vsoa_position_server_t *pos_serv;
/*
* Query callback
*/
static void query (void *arg, int domain, const char *query_name, vsoa_position_response_t *response)
{
struct sockaddr_in res;
if (strcmp(query_name, "light_server") == 0) {
if (domain < 0 || domain == AF_INET) {
bzero(&res, sizeof(struct sockaddr_in));
res.sin_family = AF_INET;
res.sin_port = htons(3001);
res.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
res.sin_len = sizeof(struct sockaddr_in);
#endif
vsoa_position_server_response(pos_serv, response,
(struct sockaddr *)&res,
sizeof(struct sockaddr_in), false);
return;
}
} else if (strcmp(query_name, "axis_server") == 0) {
if (domain < 0 || domain == AF_INET) {
bzero(&res, sizeof(struct sockaddr_in));
res.sin_family = AF_INET;
res.sin_port = htons(3002);
res.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
res.sin_len = sizeof(struct sockaddr_in);
#endif
vsoa_position_server_response(pos_serv, response,
(struct sockaddr *)&res,
sizeof(struct sockaddr_in), false);
return;
}
}
vsoa_position_server_response(pos_serv, response, NULL, 0, false);
}
/*
* main function
*/
int main (int argc, char **argv)
{
struct sockaddr_in pos_addr;
bzero(&pos_addr, sizeof(struct sockaddr_in));
pos_addr.sin_family = AF_INET;
pos_addr.sin_port = htons(3000);
pos_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
pos_addr.sin_len = sizeof(struct sockaddr_in);
#endif
pos_serv = vsoa_position_server_create(query, NULL);
if (!pos_serv) {
fprintf(stderr, "Can not create VSOA position server!\n");
return (-1);
}
if (!vsoa_position_server_start(pos_serv,
(struct sockaddr *)&pos_addr,
sizeof(struct sockaddr_in))) {
fprintf(stderr, "Can not start VSOA position server!\n");
return (-1);
}
return (0);
}
var vsoa = require('vsoa');
var socket = require('socket');
/* Demo server address */
var servers = [
{
name: 'light_server',
domain: socket.AF_INET,
addr: '127.0.0.1',
port: 3001,
security: false
},
{
name: 'axis_server',
domain: socket.AF_INET,
addr: '127.0.0.1',
port: 3002,
security: false
}
];
/* Position server */
var position = new vsoa.Position(servers, {
domain: socket.AF_INET, addr: '127.0.0.1', port: 3000
});
position.start();
import java.net.InetSocketAddress;
import com.acoinfo.vsoa.Constant;
import com.acoinfo.vsoa.Position;
import com.acoinfo.vsoa.Position.PositionItem;
public class position_test {
public static PositionItem servers[] = {
new PositionItem("light_server", Constant.AF_INET, "127.0.0.1", 3001, false),
new PositionItem("axis_server", Constant.AF_INET, "127.0.0.1", 3002, false)
};
static Position position;
public static void main(String[] args) {
position = new Position(servers, new InetSocketAddress("127.0.0.1", 3000));
position.start();
}
}
package main
import (
"net"
"gitee.com/sylixos/go-vsoa/position"
)
func PositionTest() {
/*
*Create a new position list
*/
pl := position.NewPositionList()
/*
*Add new positions to the list
*/
pl.Add(*position.NewPosition("light_server", 1, "127.0.0.1", 3001, false))
pl.Add(*position.NewPosition("axis_server", 1, "127.0.0.1", 3002, false))
/*
*Start position listener
*/
pl.ServePositionListener(net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: 3000,
})
}
func main() {
PositionTest()
}
from vsoa import Position
import socket
# Demo server address
def onquery(search: dict, reply: callable):
if search['name'] == 'light_server':
reply({ 'addr': '127.0.0.1', 'port': 3001, 'domain': socket.AF_INET })
elif search['name'] == 'axis_server':
reply({ 'addr': '127.0.0.1', 'port': 3002, 'domain': socket.AF_INET })
else:
reply(None)
# Create a position server
position = Position(onquery)
# Start position server
position.run('localhost', 3000)
步骤 3:监听事件或循环
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include "vsoa_position.h"
#include "vsoa_platform.h"
/* My position server */
static vsoa_position_server_t *pos_serv;
/*
* Query callback
*/
static void query (void *arg, int domain, const char *query_name, vsoa_position_response_t *response)
{
struct sockaddr_in res;
if (strcmp(query_name, "light_server") == 0) {
if (domain < 0 || domain == AF_INET) {
bzero(&res, sizeof(struct sockaddr_in));
res.sin_family = AF_INET;
res.sin_port = htons(3001);
res.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
res.sin_len = sizeof(struct sockaddr_in);
#endif
vsoa_position_server_response(pos_serv, response,
(struct sockaddr *)&res,
sizeof(struct sockaddr_in), false);
return;
}
} else if (strcmp(query_name, "axis_server") == 0) {
if (domain < 0 || domain == AF_INET) {
bzero(&res, sizeof(struct sockaddr_in));
res.sin_family = AF_INET;
res.sin_port = htons(3002);
res.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
res.sin_len = sizeof(struct sockaddr_in);
#endif
vsoa_position_server_response(pos_serv, response,
(struct sockaddr *)&res,
sizeof(struct sockaddr_in), false);
return;
}
}
vsoa_position_server_response(pos_serv, response, NULL, 0, false);
}
/*
* main function
*/
int main (int argc, char **argv)
{
int cnt, fd;
fd_set fds;
struct sockaddr_in pos_addr;
bzero(&pos_addr, sizeof(struct sockaddr_in));
pos_addr.sin_family = AF_INET;
pos_addr.sin_port = htons(3000);
pos_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef VSOA_HAS_SIN_LEN
pos_addr.sin_len = sizeof(struct sockaddr_in);
#endif
pos_serv = vsoa_position_server_create(query, NULL);
if (!pos_serv) {
fprintf(stderr, "Can not create VSOA position server!\n");
return (-1);
}
if (!vsoa_position_server_start(pos_serv,
(struct sockaddr *)&pos_addr,
sizeof(struct sockaddr_in))) {
fprintf(stderr, "Can not start VSOA position server!\n");
return (-1);
}
while (1) {
FD_ZERO(&fds);
fd = vsoa_position_server_fd(pos_serv);
if (fd >= 0) {
FD_SET(fd, &fds);
} else {
fprintf(stderr, "VSOA position server file error!\n");
return (-1);
}
cnt = pselect(fd + 1, &fds, NULL, NULL, NULL, NULL);
if (cnt > 0) {
vsoa_position_server_input(pos_serv);
}
}
return (0);
}
var vsoa = require('vsoa');
var socket = require('socket');
/* Demo server address */
var servers = [
{
name: 'light_server',
domain: socket.AF_INET,
addr: '127.0.0.1',
port: 3001,
security: false
},
{
name: 'axis_server',
domain: socket.AF_INET,
addr: '127.0.0.1',
port: 3002,
security: false
}
];
/* Position server */
var position = new vsoa.Position(servers, {
domain: socket.AF_INET, addr: '127.0.0.1', port: 3000
});
position.start();
require('iosched').forever();
import java.net.InetSocketAddress;
import com.acoinfo.vsoa.Constant;
import com.acoinfo.vsoa.Position;
import com.acoinfo.vsoa.Position.PositionItem;
public class position_test {
public static PositionItem servers[] = {
new PositionItem("light_server", Constant.AF_INET, "127.0.0.1", 3001, false),
new PositionItem("axis_server", Constant.AF_INET, "127.0.0.1", 3002, false)
};
static Position position;
public static void main(String[] args) {
position = new Position(servers, new InetSocketAddress("127.0.0.1", 3000));
position.start();
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
package main
import (
"net"
"gitee.com/sylixos/go-vsoa/position"
)
func PositionTest() {
/*
*Create a new position list
*/
pl := position.NewPositionList()
/*
*Add new positions to the list
*/
pl.Add(*position.NewPosition("light_server", 1, "127.0.0.1", 3001, false))
pl.Add(*position.NewPosition("axis_server", 1, "127.0.0.1", 3002, false))
/*
*Start a position listener in a separate goroutine
*/
go pl.ServePositionListener(net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: 6001,
})
}
func main() {
PositionTest()
for {
time.Sleep(1 * time.Second)
}
}
from vsoa import Position
import socket
# Demo server address
def onquery(search: dict, reply: callable):
if search['name'] == 'light_server':
reply({ 'addr': '127.0.0.1', 'port': 3001, 'domain': socket.AF_INET })
elif search['name'] == 'axis_server':
reply({ 'addr': '127.0.0.1', 'port': 3002, 'domain': socket.AF_INET })
else:
reply(None)
# Create a position server
position = Position(onquery)
# Start position server
position.run('localhost', 3000)
说明:
- 在 Node.js 的环境中,不需要事件循环。
- Python position run 执行后进入循环,不需要额外的代码保持运行状态。
注意事项
C/C++ 位置服务编译时需链接如下表所示的 VSOA 动态库,在 RealEvo-IDE 中配置时请参考 C/C++ 环境验证,Linux 下开发请参考 搭建 Linux 运行环境 提供的 C 语言范例进行配置。
库名称 | 功能 |
---|---|
libvsoa-position.so | 提供位置服务功能 |