网络程序应该注册成为系统服务,以保证其自启动以及稳定可靠运行!

这一场,讲讲怎么建立一个生产级别的网络服务。

老规矩,先上源码:https://github.com/NewLifeX/NewLife.Net

系统服务功能,由网络库的兄弟框架,X组件的Agent来支撑,以前也叫XAgent,网上搜索 NewLife XAgent 可以找到不少文章。

XAgent在X组件里面很年轻,才10年,设计于2008年,上海陆家嘴。

〇、最终效果

先来看看最终效果,大家也可以telnet net.newlifex.com 1234 来看效果

左边窗口就是这次要讲的网络服务程序,工作在调试模式。

右边窗口是上一次的EchoTest客户端,连接左边网络服务。

一、建立控制台项目

建立一个控制台项目,通过nuget引用NewLife.Core

新建一个服务类 MyService,继承自泛型基类 AgentServiceBase<MyService>

Program.Main里面增加一行引导程序:

class Program
{
static void Main(String[] args)
{
// 引导进入我的服务控制类
MyService.ServiceMain();
}
}

下面就开始慢慢完善我们的服务类MyService

public MyService()
{
ServiceName = "EchoAgent";
DisplayName = "回声服务";
Description = "这是NewLife.Net的一个回声服务示例!"; // 准备两个工作线程,分别负责输出日志和向客户端发送时间
ThreadCount = ;
Intervals = new[] { , };
}

指定一些基本参数,看效果图可以猜到用途

服务名、显示名、描述,就这么多!

ThreadCount = 2指定两个工作线程,Intervals指定它们的轮询周期分别是1秒和5秒

系统服务的标准动作就是启动和停止

MyNetServer _Server;
/// <summary>开始服务</summary>
/// <param name="reason"></param>
protected override void StartWork(String reason)
{
// 实例化服务端,指定端口,同时在Tcp/Udp/IPv4/IPv6上监听
var svr = new MyNetServer
{
Port = ,
Log = XTrace.Log
};
svr.Start(); _Server = svr; base.StartWork(reason);
} /// <summary>停止服务</summary>
/// <param name="reason"></param>
protected override void StopWork(String reason)
{
_Server.TryDispose();
_Server = null; base.StopWork(reason);
}

我们重载启动函数,初始化网络服务,并重启停止函数来销毁网络服务。

这里的MyNetServer从上一个例程拷贝过来。

网络服务做一个成员资源,避免被GC回收。

XAgent默认带来多线程任务调度,其核心是 Work(Int32 index)

/// <summary>调度器让每个任务线程定时执行Work,index标识任务</summary>
/// <param name="index"></param>
/// <returns></returns>
public override Boolean Work(Int32 index)
{
switch (index)
{
case : ShowStat(_Server); break;
case : SendTime(_Server); break;
}
return false;
} private String _last;
/// <summary>显示服务端状态</summary>
/// <param name="ns"></param>
private void ShowStat(NetServer ns)
{
var msg = ns.GetStat();
if (msg == _last) return; _last = msg; WriteLog(msg);
} /// <summary>向所有客户端发送时间</summary>
/// <param name="ns"></param>
private void SendTime(NetServer ns)
{
var str = DateTime.Now.ToFullString() + Environment.NewLine;
var buf = str.GetBytes();
ns.SendAllAsync(buf);
}

XAgent内部设计有一个任务调度器,它会实际创建2个线程(ThreadCount指定),每个线程定时执行Work(Int32 index)函数,index参数用于标识哪一个任务线程。

我们这只需要一个很简单的switch,0号线程负责输出服务端状态,每秒一次,1号线程负责给连接到服务端的所有会话发送服务器当前时间。

多说几句XAgent:

1,任务线程具有较高线程优先级,比一般线程有更多机会得到CPU时间

2,调度器有个最高优先级的管理线程,负责监管所有任务线程,如果任务线程崩溃或者超时,它会干掉并新建

3,管理线程还负责监控线程数、句柄数、内存占用等

二、开发调试

既然是控制台项目,先跑起来看看:

红色字体显示重要信息,黄色字体显示菜单,常用功能是235。

我们选择5,循环调试,其实就是在控制台里面模拟服务工作流程,让网络服务跑起来。

底下日志可以看到,它监听了4个套接字。

2是安装服务,也就是把当前应用安装成为Windows服务,这里特别注意,一般需要管理员权限,才能安装成功,除非关闭系统UAC。

3是启动服务,只有在安装了服务之后,才能看到。

所以,XAgent程序,既是开发调试控制台程序,也是安装卸载、启动停止服务的操作台,更是Windows服务程序本身!

细心的同学可以发现,安装好的Windows服务实质上就是 EchoAgent.exe -s,带有-s参数。

三、安装服务

最后,我们把它安装到一台公网服务器上,tcp://net.newlifex.com:1234,telnet上去看看效果

从日志文件可以看到,它的应用类型 ApplicationType 是 Service,也就是Windows Service。

下面的日志,在A0线程(也就是0号任务线程)输出服务端状态。

在线1/1,当前在线/最大在线

发送 2/20/0,共发送2次,最大速度每秒20字节,当前速度每秒0字节

既然有A0线程,同样也会有A1,还会有An(ThreadCount>n),可用于区分不同任务线程输出的日志。

至此,我们的Windows网络服务程序开发完成,并安装到公网服务器上,持续对外提供Echo服务!

NewLife.Net——构建可靠的网络服务的更多相关文章

  1. 使用NewLife网络库构建可靠的自动售货机Socket服务端(一)

    最近有个基于tcp socket 协议和设备交互需求,想到了新生命团队的各种组件,所以决定用NewLife网络库作为服务端来完成一系列的信息交互. 第一,首先说一下我们需要实现的功能需求吧 1,首先客 ...

  2. OpenStack 网络服务 Neutron 私有网络构建(十九)

    本章内容基于之前提供者网络构建的基础上进行改动,之前文章参考如下: Openstack 网络服务 Neutron介绍和控制节点部署 (九) Openstack 网络服务 Neutron计算节点部署(十 ...

  3. Docker 构建网络服务后本机不能访问

    Docker 构建网络服务后本机不能访问 起因 使用tornado构建了一个服务,测试都没有问题 使用docker构建镜像,使用docker run image_name启动服务 使用浏览器访问 12 ...

  4. /etc/xinetd.conf 和 /etc/xinetd.d/*【新网络服务配置】

    http://blog.csdn.net/kelven2004/article/details/1701930 xinetd 是 inetd 的安全加强版,它内置了自己的 TCP wrapper, 可 ...

  5. 深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台

    深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台 大家好,欢迎大家参加这次DC/OS的技术分享. 先做个自我介绍,刘超,Linker Networks首席架构师,Open DC/OS社区 ...

  6. Linux网络服务10——远程访问及控制

    Linux网络服务10--远程访问及控制 一.SSH概述 1.SSH简介 SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录.远程复制等功能.SSH协议对通信双方的数 ...

  7. 基于PySpark的网络服务异常检测系统 (四) Mysql与SparkSQL对接同步数据 kmeans算法计算预测异常

    基于Django Restframework和Spark的异常检测系统,数据库为MySQL.Redis, 消息队列为Celery,分析服务为Spark SQL和Spark Mllib,使用kmeans ...

  8. Web网络服务介绍

    Web网络服务也叫WWW(World Wide Web),一般是指能够让用户通过浏览器访问到互联网中文档资源服务.目前提供WEB网络服务的程序有Apache .Nginx 和  IIS  等等,Web ...

  9. Neutron三层网络服务实现原理

    Neutron 对虚拟三层网络的实现是通过其 L3 Agent (neutron-l3-agent).该 Agent 利用 Linux IP 栈.route 和 iptables 来实现内网内不同网络 ...

随机推荐

  1. Gradle 1.12 翻译——第十八章. 日志

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  2. iOS中 UITableViewRowAction tableViewcell编辑状态下的功能 UI技术分享

    * tableView:editActionsForRowAtIndexPath: // 设置滑动删除时显示多个按钮 * UITableViewRowAction // 通过此类创建按钮 * 1. 我 ...

  3. libcoro:在c++中支持coroutine

    起因 在第一个版本的libtnet开发完成之后,我一直在思考如何让异步方式的网络编程更加简单. 虽然libtnet通过c++ shared_ptr以及function等技术很大程度上面解决了异步代码编 ...

  4. JAVA之旅(九)——Object类,equals,toString,getClass,内部类访问规则,静态内部类,内部类原则,匿名内部类

    JAVA之旅(九)--Object类,equals,toString,getClass,内部类访问规则,静态内部类,内部类原则,匿名内部类 天天被一些琐事骚扰,学习还得继续 一.Object类 Obj ...

  5. Java异常处理示例

    翻译人员: 铁锚 翻译日期: 2013年11月22日 原文链接: Java Exception Handling Example 本文中有两个示例, 第一个演示了所有调用其他方法的地方,都必须处理被调 ...

  6. 阿里云服务器实战(二): Linux MySql5.6数据库乱码问题

    在阿里云上了买了一个云服务器, 部署了一个程序,发现插入数据库后乱码了,都成了'????'.  一开始怀疑是Tomcat7的原因 , 见文章 : http://blog.csdn.net/johnny ...

  7. 数据的压缩存储与解压缩算法实现(C语言)

    在一些嵌入式的项目设计中,空间是相当宝贵的,因为一个CPU的存储是有限的,所以此时我们在保存数据的时候,喜欢来进行压缩保存,著名的有哈夫曼树算法,专门用来做压缩的算法,当然,本节我们不讨论这些稍微高级 ...

  8. SparseArray到底哪点比HashMap好

    SparseArray是android里为<Interger,Object>这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch). H ...

  9. [Ext.Net]客户关系管理系统

    本人在企业中非专业人士,交流学习. 1.登录 2.系统主界面 3.用户与角色 3.菜单管理 4.角色与授权 5.登陆日志 6.简易工作流 7.客户分类 8.客户管理 9.报价管理 业务员反馈 报价明细 ...

  10. IP的种类与获取方式

    IP 的种类与取得方式 接下来要跟大家谈一谈也是很容易造成大家困扰的一个部分,那就是 IP 的种类!很多朋友常常听到什么『真实IP, 实体 IP, 虚拟 IP, 假的 IP....』烦都烦死了-其实不 ...