分类目录归档:adf

Adf.QueueServer

本文简要介绍Adf.QueueServer的一些常规应用和协议。

1. 协议描述

本服务支持 WebSocket Json/ WebSocket Binary / HTTP Json 三种通信方式
一般使用 WebSocket 做异步push/pull, 使用HTTP做同步push/pull

若同时使用多种格式JSON/BINARY,需要注意消息体(body)是否可以通过UTF8编码于二进制与字符串之间相互转化,否则可能会出现乱码情况。理论上同一队列应尽量保持使用同一种格式传输。

本服务为FIFO QUEUE,消息将保持顺序PULL,在单线程消费下消息与业务均保持顺序性。在多终端或多线程或多PULL下、消息保持顺序PULl但不保证业务执行的顺序性。

本服务支持命令:

rpush 队列右侧插入一项
lpush 队列左侧插入一项
pull 从队列中获取最左侧一项
delete 删除已从队列中pull过的项,未被pull过的项不可被删除
lcancel 恢复已pull过的项至队列左侧
rcancel 恢复已pull过的项至队列右侧
count 查询队列长度
clear 清空队列项

2. JSON格式

字符编码格式: UTF8

//push request:
{
 "action":"lpush/rpush",
 "requestid":"1 ~ 32 chr.  propose use uuid",
 "queue": "/order/new",
 "body":"this is a test message."
}

//push response:
{
 "action":"lpush/rpush",
 "requestid":"88bea088837d4743af67a2d49e6d08d1",
 "queue": "/order/new",
 "result":"ok or failure message",
 "messageid": 1452443242
}

//delete/lcancel/rcancel/createqueue/deletequeue/count/clear/pull request:
{
 "action":"delete/lcancel/rcancel/createqueue/deletequeue/count/clear/pull",
 "requestid":"1 ~ 32 chr.  propose use uuid",
 "queue": "/order/new"
}

//delete/lcancel/rcancel/createqueue/deletequeue response:
{
  "action":"delete/lcancel/rcancel/createqueue/deletequeue",
  "requestid":"88bea088837d4743af67a2d49e6d08d1",
  "queue": "/order/new",
  "result":"ok or failure message"
}

//count/clear response:
{
  "action":"count/clear",
  "requestid":"88bea088837d4743af67a2d49e6d08d1",
  "queue": "/order/new",
  "result":"ok or failure message",
  "count":0
}

//pull response:
{
	"action":"pull",
	"requestid":"88bea088837d4743af67a2d49e6d08d1",
	"queue": "/order/new",
	"result":"ok or failure message",
	"body":"message body.",
	"duplications": 0,
	"messageid": 1452443242
}

2. 二进制传输格式

Endianness : Big-Endian
Body: UTF8

二进制元素内容与JSON结构一致。

//type:
action		: byte
xx length	: uint16 
duplications: uint16
count		: int32
messageid	: uint64


//push request:
+---------------------------------------------------------------+
|	action (1)
+---------------------------------------------------------------+
|	id length (2)
+---------------------------------------------------------------+
|	id  (1 ~ 65535)
+---------------------------------------------------------------+
|	queue length (2)
+---------------------------------------------------------------+
|	queue (1 ~ 65535)
+---------------------------------------------------------------+
|	body length (2)
+---------------------------------------------------------------+
|	body (1 ~ 65535)
+---------------------------------------------------------------+

//push response:
+---------------------------------------------------------------+
|	action (1)
+---------------------------------------------------------------+
|	id length (2)
+---------------------------------------------------------------+
|	id  (1 ~ 65535)
+---------------------------------------------------------------+
|	queue length (2)
+---------------------------------------------------------------+
|	queue (1 ~ 65535)
+---------------------------------------------------------------+
|	result length (2)
+---------------------------------------------------------------+
|	result (1 ~ 65535)
+---------------------------------------------------------------+
| OK | messageid length (8)
+---------------------------------------------------------------+


//delete/lcancel/rcancel/createqueue/deletequeue/count/clear/pull request:
+---------------------------------------------------------------+
|	action (1)
+---------------------------------------------------------------+
|	id length (2)
+---------------------------------------------------------------+
|	id  (1 ~ 65535)
+---------------------------------------------------------------+
|	queue length (2)
+---------------------------------------------------------------+
|	queue (1 ~ 65535)
+---------------------------------------------------------------+

//delete/lcancel/rcancel/createqueue/deletequeue response:
+---------------------------------------------------------------+
|	action (1)
+---------------------------------------------------------------+
|	id length (2)
+---------------------------------------------------------------+
|	id  (1 ~ 65535)
+---------------------------------------------------------------+
|	queue length (2)
+---------------------------------------------------------------+
|	queue (1 ~ 65535)
+---------------------------------------------------------------+
|	result length (2)
+---------------------------------------------------------------+
|	result (1 ~ 65535)
+---------------------------------------------------------------+

//count/clear response:
+---------------------------------------------------------------+
|	action (1)
+---------------------------------------------------------------+
|	id length (2)
+---------------------------------------------------------------+
|	id  (1 ~ 65535)
+---------------------------------------------------------------+
|	queue length (2)
+---------------------------------------------------------------+
|	queue (1 ~ 65535)
+---------------------------------------------------------------+
|	result length (2)
+---------------------------------------------------------------+
|	result (1 ~ 65535)
+---------------------------------------------------------------+
| OK | count (4)
+---------------------------------------------------------------+

//pull response:
+---------------------------------------------------------------+
|	action (1)
+---------------------------------------------------------------+
|	id length (2)
+---------------------------------------------------------------+
|	id  (1 ~ 65535)
+---------------------------------------------------------------+
|	queue length (2)
+---------------------------------------------------------------+
|	queue (1 ~ 65535)
+---------------------------------------------------------------+
|	result length (2)
+---------------------------------------------------------------+
|	result (1 ~ 65535)
+---------------------------------------------------------------+
|	 | body length (2)
+    -----------------------------------------------------------+
|	 | body (1 ~ 65535)
+ OK -----------------------------------------------------------+
|    | duplications (2)
+    -----------------------------------------------------------+
|    | messageid (8)
+---------------------------------------------------------------+


3. HTTP 请求

字符编码: UTF8
元素与JSON结构一致,但在请求时除rpush/lpush时的body以外,其它所有元素均以Queue String方式进行传递。
返回结果与同JSON结构
以.json后缀的接口,返回JSON
以.bin 后缀的接口,返回二进制数据

PATH METHOD REMARKS
/queue/rpush.json?queue=&requestid=
/queue/rpush.bin?queue=&requestid=
POST application/octet-stream
内容为消息实体BODY
/queue/lpush.json?queue=&requestid=
/queue/lpush.bin?queue=&requestid=
POST application/octet-stream
内容为消息实体BODY
/queue/pull.json?queue=&requestid=
/queue/pull.bin?queue=&requestid=
GET 拉取一个消息
/queue/delete.json?queue=&requestid=
/queue/delete.bin?queue=&requestid=
GET 删除一个已拉取消息
/queue/lcancel.json?queue=&requestid=
/queue/lcancel.bin?queue=&requestid=
GET 恢复一个已拉取消息至队列左侧
/queue/rcancel.json?queue=&requestid=
/queue/rcancel.bin?queue=&requestid=
GET 恢复一个已拉取消息至队列右侧
/queue/count.json?queue=&requestid=
/queue/count.bin?queue=&requestid=
GET 获取一个队列元素数
/queue/clear.json?queue=&requestid=
/queue/clear.bin?queue=&requestid=
GET 清空一个队列元素

4. Websocket

Binary ws://{host}:{port}/queue/bin
Json  ws://{host}:{port}/queue/json

同一个ws连接允许同时多个PULL请求。

5. RequestID 描述

协议中 RequestID 为请求标识,不做为消息标识,该标识由使用者自行生成,可以是1-32位字符,除PULL以外的其它所有命令均允许该体重复。

在PULL时若使用websocket则必需保证同一连接中不重复,常在同一连接中使用递增数做为标识。若使用http则需保证http全局不重复。 不能重复是因为PULL的标识需在要delete/lcancel/rcancel时做为识别标识使用。

6. Action 描述

编码如下

const byte LPUSH = 1;
const byte RPUSH = 2;
const byte DELETE = 3;
const byte PULL = 4;
const byte CLEAR = 5;
const byte COUNT = 6;
const byte LCANCEL = 7;
const byte RCANCEL = 8;
const byte CREATEQUEUE = 9;
const byte DELETEQUEUE = 10;
const string OK = "ok";

7. 消息事务模式

本服务原生支持事务模式, 不支持非事务模式的消息消费,所有消息在消费后必需通过delete命令删除;
若终端在处理业务时认为是一个失败的业务消费可以通过lcancel/rcancel将消息退回至队列的左侧或右侧;
面向连接使用方式,若不进行delete操作,则在连接断开后将自动恢复至队列左侧;
消息每被退回后再次PULL一次则duplications将为递增1,通常可以通过该值来判断该消息是否为被初次消费,若不是被初次消费则应检查重复消费所导致的脏数据或重复数据,如:不应产生两次相同的订单或扣款。

 

Adf.NumberServer v2.0.0 manual

本文简要介绍Adf.NumberServer在windows平台下的使用。
本服务常用于生成用户标识,订单标识,会话标识等场景。

1.  协议描述

服务完全兼容 memcached 文本协议, 使用支持1.2.0 或以上版本的任意一款客户端均可访问,不区分语言,本服务仅支持 set,incr,decr,get,stats 五个命令,其它命令均不受支持。

Protocol:
https://github.com/memcached/memcached/blob/1.6.0-beta1/doc/protocol.txt

根据协议:

incr 可至int64最大值,超过最大值后将会归零后循环,
decr 可至最小值0,低于0值时会保持0值,不会出现负数。

2.  键约束

本服务支持最长KEY为 250字符, 超过该长度服务将会出现异常。
本服务不支持多字节KEY, 仅支持ASCII字符。

3.  单机模式

在数据不要求安全的情况下,本服务支持单机模式。
单机模式时需要将配置文件中所有以HA:方式开始的配置禁用或删除掉。

4.  高可用模式(High-Availability)

本服务基于 adf.service 组件, 支持master/slave/witness 的高可用方式,为提高可用性,master与slave通信为实时同步而保持数据的绝对一致性。

启用HA需配置:
HA:Path                高可用配置数据存储路径
HA:Node1             默认的master服务
HA:Node2             默认的slave服务
HA:Node3             默认的witness 服务

注意:本服务在高可用环境时, 只有master会对外提供服务,其它两个节点不会对外提供服务,因此,你的客户端需要能自动的判断节点的可用性。

5.  主备切换

本服务允许你直接停掉master主机来进行手动的主备切换,主机停止后slave将自动成为master以提供服务。
当有需要再次启动原master时,原master节点将会以slave成员启动。

注意:你不能手动的频繁来回切换,因为数据复制原因,你必需确定现slave成员的日志文件中出现 replication client: request replicate sync 日志后再进行回切, 否则有可能出现数据丢失。

6.  下载与安装

通过以下连接下载:
http://www.aooshi.org/adf/download/Adf.NumberServer-2.0.0.zip
http://www.aooshi.org/adf/doc/adf.numberserver-2.0.0-manual.pdf

工具描述:
ToolInstallService             用于将应用以服务方式安装至系统
ToolRunConsole               手动运行应用
ToolUninstallService            用于卸载已安装在系统中的应用

7.   配置说明

区分大小写

Port 服务端口,默认为: 6224
Ip 允许配置本机IP或 * , * 表示当前设备的所有网络接口。
DataPath 数据存储路径
Log:FlushInterval 日志刷新间隔, 建议值: 5s
Log:Path 日志存储路径。
HA:Node1 高可用模式的Master节点
HA:Node2 高可用模式的Slave节点
HA:Node3 高可用模式的Witness节点
HA:Keepalive 高可用模式节点检测间隔,默认: 5s
HA:ElectTimeout 高可用模式Master节点选举超时时间,默认:5s
HA:Mails 高可用模式时 节点变化通知邮件收件人

8.   模糊查询协议扩展

在原服务协议基础上,增加模糊查询命令扩展。
get * {prefix} {size}
*               获取模糊匹配,第一个*  表示模糊匹配模式
prefix        表示需要匹配的键前缀
size           表示需要返回的条数

get * * 10
上述命令将获取所有键中的任意 10 条数据

get * * 100
上述命令将获取所有键中的任意 100 条数据

get * ab 10
上述命令将获取所有键以ab开始的的任意10 条数据

get * am 10
上述命令将获取所有键以am开始的的任意10 条数据

匹配:  amaooshi,  amtom
不匹配: name,  toam

9.    使用Adf.MemcachePool 示例

配置添加:

将下列配置中的IP地址更换为自已的

<configSections>
<section name="NumberServer" type="Adf.Config.IpGroupSection,Adf"/>
</configSections>

<NumberServer>
<!-- HA:Node1 -->
<add ip="192.168.199.14" port="6224"/>
<!-- HA:Node1 -->
<add ip="192.168.199.13" port="6224"/>
</NumberServer>

添加类:

public class NumberServerClient : Adf.MemcachePool
{
public static readonly Adf.MemcachePool Instance = new Adf.MemcachePool("NumberServer");
}

使用与示例:

long userId = NumberServerClient.Instance.Increment("userid");
long userId = NumberServerClient.Instance.Increment("id.user.net.cn");
long productId = NumberServerClient.Instance.Increment("/product1/id");
long p2Id = NumberServerClient.Instance.Increment("/product2/id");
long p3Id = NumberServerClient.Instance.Increment("/product3/id");
long orderId = NumberServerClient.Instance.Increment("/order/id");
long bookId = NumberServerClient.Instance.Increment("/book/id");
long bookId = NumberServerClient.Instance.Increment("id.book.net.cn");


 

 

 

Adf.Smtp

配置描述:

默认实例可通过Smtp.Config,  Global.Config, AppSetting 配置

优先级以 AppSetting->Global.Config->Smtp.Config

 

配置项:

 

SmtpEnabled:    是否启用 ,必需,值为 true/false

SmtpHost:    主机地址,例: smtp.mail.com,非必需

SmtpPort:    端口,非必需, 默认为 25

SmtpAccount:    在配置了SmtpHost时,登录主机的帐号,非必需

SmtpPassword:    在配置了SmtpHost时,登录主机的帐号,非必需

SmtpSender:    默认的邮件发送者地址,与SmtpSenderRandomDomain互斥,非必需

SmtpName:    默认的发送者显示名称,非必需

SmtpSSLEnabled:    是否启用SSL登录,默认false,非必需

SmtpSenderRandomDomain:    默认随机产生邮件发送地址的域名部份与SmtpSender互斥,非必需

 

注:以上SmtpSender / SmtpSenderRandomDomain必需配置或在应用程式中设置一个

 

配置示例:

Smtp.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <!-- 是否启用 -->
  <item name="SmtpEnabled" value="true"/>
  <!-- 发送主机 -->
  <item name="SmtpHost" value="smtp.mymail.com" />
  <!-- 发送端口 -->
  <item name="SmtpPort" value="25" />
  <!-- 登录主机的帐户 -->
  <item name="SmtpAccount" value="" />
  <!-- 登录主机的帐户名 -->
  <item name="SmtpPassword" value="" />
  <!-- 邮件默认发送者, 此配置与SmtpSenderRandomDomain互斥 -->
  <item name="SmtpSender" value="" />
  <!-- 邮件默认发送显示名 -->
  <item name="SmtpName" value="" />
  <!-- 是否启动SSL连接-->
  <item name="SmtpSSLEnabled" value="" />
  <!-- 默认邮件发送使用的随机发送地址域名部份,为空时不启用, 此配置与SmtpSender互斥 -->
  <item name="SmtpSenderRandomDomain" value="" />


</configuration>

 

 

 

 .

Adf.Cs 使用 Adf.RegistryServer

参阅:

Adf.cs

http://www.xiaobo.li/adf/513.html

Adf.RegistryServer

http://www.xiaobo.li/adf/516.html

 

客户端支持, 配置模式及注册中心模式

两种模式使用方式完全一致,仅配置节定义区别,如下:

 

配置模式:

<section name="TestServer" type="Adf.Config.IpGroupSection,Adf"/>

 

注册中心模式:

<section name="TestServer" type="Adf.Cs.CsRegistrySection,Adf.Cs"/>

 

完整配置参考:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="TestServer" type="Adf.Config.IpGroupSection,Adf"/>
    <!--<section name="TestServer" type="Adf.Cs.CsRegistrySection,Adf.Cs"/>-->
  </configSections>
  <appSettings>
    <add key="Log:Path" value="c:\Logs\Adf.Cs\TestClient"/>
    <!-- 日志刷新时间间隔(秒) -->
    <add key="Log:FlushInterval" value="10"/>
    <!-- 日志禁用 -->
    <!--<add key="Log:Disabled" value="all"/>-->
  </appSettings>
  <!-- Servers -->
  <TestServer>
    <!--<add ip="127.0.0.1" port="200"/>-->
    <add ip="127.0.0.2" port="4562"/>
    <add ip="127.0.0.3" port="4562"/>
    <add ip="127.0.0.4" port="4562"/>
  </TestServer>
</configuration>

.

Adf.RegistryServer 应用

应用及安装文章:

http://www.xiaobo.li/adf/516.html

 

安装完成后,通过以下方式调用:

以此配置为例: 

<!-- 服务监听IP,不指定默认本机接口 -->
<add key="ServiceMonitorIp" value="127.0.0.1"/>
<!-- 服务监控端口 -->
<add key="ServiceMonitorPort" value="200"/>

 

主机地址: http://127.0.0.1:200

 

注册一个主机到组:

HTTP POST:            http://127.0.0.1:200?action=register

POST DATA:

{
    "group":"group name",        //register group name
    "host":"ip",
    "port":0
    "custom attr1":""        //custom attribute 1
    "custom attr2":""        //custom attribute 2
        ...
    "custom attrN":""        //custom attribute N
}

 

获取一组注册主机:

HTTP GET:             http://127.0.0.1:200?action=get&group={group name}

 

 

Adf.Service

通过 Adf.Service 嵌入,可简单实现一个 .Net 项目的 windows 服务

 

下载:

Adf.Service        http://www.aooshi.org/adf/download/Adf.Service.1.3.zip


源码:

http://www.aooshi.org/adf


应用:

1. 创建控制台应用程序, 版本2.0或以上
2. 引用: adf.dll, adf.service
3. 修改:  Program为共公public访问符
4. Program 继承Adf.Service.IService, Main 函数调用 Adf.Service.ServiceHelper.Entry(args);
5. 建立:  app.config 文件,并配置 ServiceMonitorPort
6. 复制 Tool*.bat 并修改Adf.Service.Test为你的应用程序

Program.cs 参考:

using System;
using System.Collections.Specialized;

namespace Adf.Service.Test
{
    /// <summary>
    /// 程序入口
    /// </summary>
    public class Program : IService
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Adf.Service.ServiceHelper.Entry(args);
        }

        public void Initialize(ServiceContext serviceContext)
        {
            //注册当前服务至注册中心
            //serviceContext.MonitorToRegistry();
        }

        public void Start(ServiceContext serviceContext)
        {
            serviceContext.Logger.Message.WriteLine("My Service Start");
        }

        public void Stop(ServiceContext serviceContext)
        {
            serviceContext.Logger.Message.WriteLine("My Service Stop");
        }

        public System.Net.HttpStatusCode HttpAction(string action, ServiceContext serviceContext, HttpServerContext httpServerContext)
        {
            serviceContext.Logger.Message.WriteLine("httpaction:" + httpServerContext.Url);
            return System.Net.HttpStatusCode.OK;
        }


        public string Status(ServiceContext serviceContext, NameValueCollection queryString)
        {
            return string.Empty;
        }

        public void Dispose()
        {

        }
    }
}

配置参考:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="cluster" type="Adf.Config.IpGroupSection,Adf"/>
    <section name="Registry" type="Adf.Config.IpGroupSection,Adf"/>
    <section name="Authorization" type="System.Configuration.DictionarySectionHandler" />
  </configSections>
  <appSettings>

    <!-- 服务监控IP,不配置则仅本机可浏览 -->
    <!--<add key="ServiceMonitorIp" value="*"/>-->
    
    <!-- 服务监控端口 -->
    <add key="ServiceMonitorPort" value="8456"/>
     <!--日志刷新值--> 
    <add key="Log:FlushInterval" value="10"/>
    <!-- 日志路径 -->
    <add key="Log:Path" value="c:\log\adf.service"/>   

    <!-- 禁止安装完成后自动启动 -->
    <!--<add key="ServiceInstalledStart" value="false"/>-->

    <!-- 服务使用的帐户,默认: LocalSystem, 还可系统帐户 LocalService,NetworkService 系统帐户时不配置密码, 自建帐户需配置密码 --> 
    <!--<add key="ServiceUsername" value=""/>-->
    <!--<add key="ServicePassword" value=""/>-->
    
    <!-- 本服务依赖的服务清单,多个以半角分号隔开 -->
    <!--<add key="ServiceDepended" value="server1;server2;server3"/>-->
  </appSettings>

  <!-- Cluster Check Interval, seconds,default 10 -->
  <!--<cluster check="1">
    <add ip="127.0.0.1" port="8456" level="1" />
    <add ip="127.0.0.2" port="8456" />
    <add ip="127.0.0.3" port="8456" />
  </cluster>-->

  <!-- Registry Server List, check is register period,  suggest: ip use dns name  -->
  <!--<Registry check="60">
    <add ip="127.0.0.1" port="200" />
  </Registry>-->

  <!-- 允许访问的用户名及密码 -->
  <!--<Authorization>
    <add key="username1" value="password" />
    <add key="username2" value="password" />
  </Authorization>-->
  
  <startup>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>

 

调试:

调试配置

1、 右键项目->属性->调试->命令行参数->输入 /c

如图:

点击查看原图

配置完成后按 F5 启动应用

 

监控面板:

此服务自带监控面板

http://ServiceMonitorIp:ServiceMonitorPort /

示例: http://127.0.0.1:8456

 

 

其它:

服务应用成功后, 在Start 方法中初始化一个Adf.Cs.ServerListen 可以搭建一个Cs项目

CS 应用参考 :http://www.xiaobo.li/adf/513.html

参考:

Adf.Cs.ServerListen listen;
public void Start(Adf.Service.ServiceContext serviceContext)
{
    this.listen = new Adf.Cs.ServerListen(serviceContext.Logger);
    //是否自动注册到注册中心
    if (serviceContext.Registry.Enable)
    {
        var node = new Dictionary<string, object>();
        node.Add("group", serviceContext.Setting.ServiceName);
        node.Add("port", this.listen.Port);

        serviceContext.Registry.RegisterNode(node);
    }
}
public void Stop(Adf.Service.ServiceContext serviceContext)
{
    this.listen.Dispose();
}

 

 

 

 

Adf.RegistryServer Install

Adf.RegistryServer 是一个常规主机注册服务

 

下载:

http://www.aooshi.org/adf/download/Adf.RegistryServer.1.0.zip

源代码:

http://www.aooshi.org/adf/

 

安装:

下载后解压

点击目录下 ToolInstallService.bat 进行安装

非管理员时请点击右链选择”以管理员运行“

 

配置说明:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="Authorization" type="System.Configuration.DictionarySectionHandler" />
  </configSections>
  <appSettings>
    <!-- 服务监听IP,不指定默认本机接口 -->
    <!--<add key="ServiceMonitorIp" value="127.0.0.1"/>-->
    <!-- 服务监控端口 -->
    <add key="ServiceMonitorPort" value="200"/>
    <!-- 日志存储路径 -->
    <add key="Log:Path" value="C:\Logs\Adf.RegistryServer"/>
    <!-- 日志刷新时间间隔(秒) -->
    <add key="Log:FlushInterval" value="10"/>
    <!-- 检查周期(秒) -->
    <add key="InspectInterval" value="5"/>
    <!-- 检测成功上线阀值 -->
    <add key="UpThreshold" value="3"/>
    <!-- 检测失败下线阀值 -->
    <add key="DownThreshold" value="3"/>
    
  </appSettings>
  <!-- 允许访问的用户名及密码 -->
  <!--<Authorization>
    <add key="username1" value="password" />
    <add key="username2" value="password" />
  </Authorization>-->
  <startup>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>

参数 ServiceMonitorIp 数默认注释掉,仅本机可加接, 若需其它主机能连接 打开配置并设置值为  *

<add key="ServiceMonitorIp" value="*"/>

 

授权:

默认配置不开启授权, 需要授权时,配置  Authorization 节点,填写相应的帐户名或密码

 

监控面板:

http://host:port/

ServiceMonitorPort 端口默认: 200

示例: http://127.0.0.1:200


点击查看原图

应用参考:

http://www.xiaobo.li/adf/518.html

.

 

adf.cs

使用方法简介:

    下载及源码: http://www.aooshi.org/adf

 

项目添加引用:

Adf.dll

Adf.Cs.dll

protobuf-net.dll

三个程序集

 

创建通信接口,示例:

注: 不能含有泛型成员,不能是嵌套类型(类中类)

/// <summary>
/// 业务接口
/// </summary>
public interface ITest
{
    /// <summary>
    /// 告知服务器客户端时间
    /// </summary>
    /// <param name="time"></param>
    /// <returns></returns>
    bool NotifyTime(DateTime time);

    /// <summary>
    /// 返回一个指定SIZE的数组
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    int[] GetArray(int size);

    /// <summary>
    /// 获取一个分页数据,并指定pageindex,pagesize参数做为hash键
    /// </summary>
    /// <param name="pageindex"></param>
    /// <param name="pagesize"></param>
    /// <param name="totalcount"></param>
    /// <returns></returns>
    [ClientHashKey("pageindex", "pagesize")]
    int[] GetDatas(int pageindex,int pagesize, out int totalcount);
}

 

创建服务端业务,以实例接口,示例:

/// <summary>
/// 服务端示例
/// </summary>
public class TestServer : Adf.Cs.Example.ITest
{
    //注意: 为了安全,用于CS的方法必需标记Command,不标记的为本地方法。 
    //不标记的情况下客户端请求将会出现找不到命令的异常

    /// <summary>
    /// 告知我客户端时间
    /// </summary>
    /// <param name="time"></param>
    /// <returns></returns>
    public bool NotifyTime(DateTime time)
    {
        //收到时间了,返回 true
        return true;
    }

    /// <summary>
    /// 返回指定大小的一组数据
    /// </summary>
    /// <param name="size"></param>
    /// <returns></returns>
    public int[] GetArray(int size)
    {
        var rand = new Random();
        var result = new int[ size ];
        for (int i = 0; i < size; i++)
        {
            //随机生成一个数
            result[i] = rand.Next();
        }
        return result;
    }

    /// <summary>
    /// 返回一个分页数据
    /// </summary>
    /// <param name="pageindex"></param>
    /// <param name="pagesize"></param>
    /// <param name="totalcount"></param>
    /// <returns></returns>
    public int[] GetDatas(int pageindex, int pagesize, out int totalcount)
    {
        //因为是示例,此处业务不完整, 直接返回指定尺寸数据
        totalcount = int.MaxValue;
        return this.GetArray(pagesize);
    }
}    

服务端启动配置,示例

            var logManager = new Adf.LogManager("test");
            var listen = new Adf.Cs.ServerListen(logManager);

服务端需要的配置,示例

<configSections>
    <section name="ServerMap" type="System.Configuration.NameValueSectionHandler"/>
  </configSections>
  <!-- 服务映射 -->
  <ServerMap>
    <!-- 客户端Test映射到 Adf.Cs.ExampleServer 程序集的 Adf.Cs.ExampleServer.TestServer 类 -->
    <add key="Test" value="Adf.Cs.ExampleServer.TestServer,Adf.Cs.ExampleServer"/>
  </ServerMap>
  <appSettings>
    <!-- 服务端口 -->
    <add key="Port" value="4562"/>
    <!-- 日志存储路径 -->
    <add key="Log:Path" value="D:\logs\Adf.Cs\TestServer"/>
    <!-- 日志刷新时间间隔(秒) -->
    <add key="Log:FlushInterval" value="10"/>

  </appSettings>

创建客户端,示例:

/// <summary>
/// 测试客户端
/// </summary>
public static class TestClient
{
    //指示服务名为:           Test
    //服务器为配置文件中的:   TestServer 节点

    /// <summary>
    /// 通用实例
    /// </summary>
    public static ITest Instance = Adf.Cs.CsHelper.GetClient<ITest>("Test", "TestServer");


}

使用示例:

 var notifyResult = TestClient.Instance.NotifyTime(DateTime.Now);
Console.WriteLine("告诉服务器客户端时间:" + notifyResult);

var array = TestClient.Instance.GetArray(5);
Console.WriteLine("从服务器获取到数据:" + Adf.ConvertHelper.ArrayToString(array, ","));

var totalcount = 0;
var datas = TestClient.Instance.GetDatas(1, 10, out totalcount);
Console.WriteLine("从服务器获取第1页数据:" + totalcount + Adf.ConvertHelper.ArrayToString(datas, ","));
Console.WriteLine("数据在服务器的总量为:"+ totalcount);

客户端需要的配置:

  <configSections>
    <section name="TestServer" type="Adf.Config.IpGroupSection,Adf"/>
  </configSections>
  <appSettings>
    <!-- 日志存储路径 -->
    <add key="Log:Path" value="C:\Logs\Adf.Cs\TestClient"/>
    <!-- 日志刷新时间间隔(秒) -->
    <add key="Log:FlushInterval" value="10"/>
  </appSettings>
  <!-- Servers 指定, 当前仅开放一个服务 -->
  <TestServer hash="0">
    <add ip="127.0.0.1" port="4562"/>
  </TestServer>

 

示例项目下载:

  http://www.aooshi.org/adf/download/Adf.Cs.1.x.Example.zip

 

 

Adf 开发项目结构建议

共享程序集位置

所有开发人员必需具有,c:\develop\bin 目录,此目录用于存放共享程序集、第三方插件集等程序集,此目录由应该使用 https://svn.aooshi.org:8080/svn/adf/bin  导出/检出。若有共享库,第三方库均应签入此版本管理库中

若遇个别项目无法生成,缺少程序集,可SVN Update 此目录
 

WEB项目标准结构

所有项目标准结构如下(Example 为项目名举例)

建立 Web Application 项目, 项目名为  Example

Example

n  Logic                    逻辑层目录

n  PageBase.cs             通用网页基类

n  Helper.cs                    通用工具库

n  Entity                            实体目录

n  SqlServer                     SqlServer 数据库访问代码目录(项目SqlServer时存在)

n  Factory.cs                  数据库连接器

n  Mysql                           MySql 数据库访问代码目录(项目MySql 时存在)

n  Api                                          接口所在目录,统一使用 ashx 一般应用程序,ajax接口

n  Config                                    配置文件目录(非必需)

n  Static                                               项目用静态文件地址

n  styles                          样式、字体文件目录(注意:小写严格遵守)

n  images                        项目用图片目录(注意:小写严格遵守)

n  scripts                         脚本目录(注意:小写严格遵守)

n  Upfiles                                   文件上传目录(若需要)

n  Alipay                                     支付宝所有接口目录(仅一级)(项目需要时存在)

n  Users                                              项目用户目录(大量操作时使用)

n  Index.aspx                                     索引首页(所有项目均以Index.aspx为首页)

 

根据以上规则,所有对外接口项目均建立一个目录,除特殊性况外,均使用一级目录。

遵循以上目录结构,每一个大模块均建立一级目录用于存储。

常规项目所有网页文件均存放至根目录,不建立块项目录,当某个模块网页量大于100或特殊安全要求,商议建立目录

数据库目录下(如: SqlServer/MySql)基本保证每表一类,Logic目录为逻辑类,以模块划分,比如: 用户,日志,支付等

项目参考: https://svn.aooshi.org:8080/svn/adf/tags/examples/

 

数据访问与ADF框架

除数据库目录文件外(如:SqlServer目录),不允许在其它位置出现Sql语句,如: 网页中。

 

所有进行直接拼接的语句,只要参数为字符串必需进行 安全转换(db. InjectReplace

 

统一使用ADF 数据操作基类进行数据访问,代码地址: http://www.aooshi.org/adf

 

在线帮助: http://www.aooshi.org/adf/help

离线帮助: http://www.aooshi.org/adf/help/Adf.Documentation.chm

实体生成器: http://www.aooshi.org/adf/db/download/

 

使用方式参考 Example 项目

实体生成方式:

实体生成器下载后解压, 配置Adf.Db.Desktop.exe.config 文件

connectionStrings 节点添加一个数据库连接,名字为库名,此处以Example为例

DbMap 节点添加一项:

1、  名字为项目名字(Example)

2、  target为刚添加的数据库名

3、  namespace 为你的项目+Entity (如:Example.Entity)

4、  factory 为你的数据库操作类(如:Example.DbFactory

<add name="Example" target="Example"

namespace=" Example.Entity " factory=" Example.DbFactory "/>

 

注意:BaseClass 配置项,若需要进行实体类更新需则需要填写 DbEntity, 否则该项中不应出现此值

 

假定一个数据库连接:  192.168.1.200,  ID=sa,  pwd=sa 示例:

<connectionStrings>

<add name="Example"

connectionString="Data Source=192.168.1.200;User Id=sa;Password=sa;Initial Catalog=Example;"

providerName="SQLServer"/>

  </connectionStrings>

  <DbMap>

<add name="Example" target="Example" namespace="Example.Entity"

logicnamespace="Example.Logic" factory="Example.DbFactory"/>

  </DbMap>

 

配置后保存,双击 Adf.Db.Desktop.exe 运行

 

点击查看原图

点击查看原图

点击查看原图

复制代码至你的项目或  Save As 存储文件

 

基本表方法生成:

点击查看原图

点击查看原图

复制代码至你的项目相应DB文件或  Save As 存储文件

 

 

 

 

Adf

Aooshi DotNet Framework (Adf)

PS:原名 Aooshi.dll  自3.7版本起更名为 Adf

 

Source(源代码授权):

User(帐户): readonly
Pass(密码): readonly

Aooshi(源代码):

https://svn.aooshi.org:8080/svn/adf/tags/aooshi/3.7

 

Adf(源代码):

https://svn.aooshi.org:8080/svn/adf/tags/adf/4.2

https://svn.aooshi.org:8080/svn/adf/tags/adf.cs/1.2

https://svn.aooshi.org:8080/svn/adf/tags/adf.cs/1.3

https://svn.aooshi.org:8080/svn/adf/tags/adf.scheduler/1.0

https://svn.aooshi.org:8080/svn/adf/tags/adf.service/1.0

https://svn.aooshi.org:8080/svn/adf/tags/db/2.2

https://svn.aooshi.org:8080/svn/adf/tags/IdGenerate/1.0

https://svn.aooshi.org:8080/svn/adf/tags/adf.registryserver/1.0/

https://svn.aooshi.org:8080/svn/adf/tags/TaskScheduler/1.0

https://svn.aooshi.org:8080/svn/adf/bin

 

Download(下载):

http://www.aooshi.org/adf/download

http://www.aooshi.org/adf/download/Adf.4.5.2.zip

http://www.aooshi.org/adf/download/Adf.Web.4.5.2.zip

http://www.aooshi.org/adf/download/Adf.Service.1.3.zip

http://www.aooshi.org/adf/download/Adf.Scheduler.2.0.zip

http://www.aooshi.org/adf/db/

http://www.aooshi.org/adf/download/Adf.Cs.1.4.zip

http://www.aooshi.org/adf/download/Adf.CacheServer-1.0.zip

http://www.aooshi.org/adf/download/Adf.SessionServer-1.0.zip

 

SVN Download:

svn checkout https://svn.aooshi.org:8080/svn/adf/bin c:\develop\bin\adf4

Help(在线帮助文档):

http://www.aooshi.org/adf/help

Help(离线帮助文档):

http://www.aooshi.org/adf/help/Adf.Documentation.chm

Adf Db Help:

http://www.aooshi.org/adf/db/

http://www.xiaobo.li/adf/417.html

Adf Db :

http://www.aooshi.org/adf/db/demo

Adf.Cs :

http://www.xiaobo.li/adf/513.html

Adf.Service :

http://www.xiaobo.li/adf/517.html

Adf.RegistryServer :

http://www.xiaobo.li/adf/516.html

AdwEngine:

http://wiki.aooshi.org/doku.php?id=adwengine

 

一些示例:

SVN:  https://svn.aooshi.org:8080/svn/adf/tags/examples/

Adf 开发项目结构建议: http://www.xiaobo.li/adf/417.html