通用主机
定义
命名空间:TouchSocket.Hosting
程序集:TouchSocket.Hosting.dll
程序集:TouchSocketPro.Hosting.dll
一、说明
Hosting通用主机,是在创建一个HostBuilder 之后,可以通过Add的服务的形式创建TouchSocket
的一些组件。如TcpService
、TcpClient
、NamedPipeService
、NamedPipeclient
等。
二、安装Nuget包
在安装Nuget之前,最好先确认目标项目是一个主机项目。例如:辅助角色服务模板、 AspNetCore等。如果是其他项目,请自行解决依赖。
使用Nuget安装TouchSocket.Hosting
、TouchSocketPro.Hosting
、TouchSocket.AspNetCore
、TouchSocketPro.AspNetCore
其中的任意一个。
TouchSocket.Hosting
、TouchSocketPro.Hosting
、TouchSocket.AspNetCore
、TouchSocketPro.AspNetCore
都可以安装使用。主要区别就是:Hosting的只包含基础扩展。AspNetCore的会对Web项目有更多扩展。
一般建议Web项目使用TouchSocket.AspNetCore
、TouchSocketPro.AspNetCore
。辅助角色项目、MAUI项目等使用TouchSocket.Hosting
、TouchSocketPro.Hosting
。
三、添加服务器类
一些常用的服务器组件,都已经被封装了,可以直接使用。例如:
- TcpService
- UdpService
- TcpDmtpService(由TouchSocket.AspNetCore提供)
没被封装的组件只是没直接提供扩展方法,而不是不能使用。具体操作请看下文。
3.1 在Aspnetcore中添加
下列示例只配置了监听端口,更多配置请看TcpService。
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
...
#region 添加Tcp服务器
builder.Services.AddTcpService(config =>
{
config.SetListenIPHosts(7789);
});
#endregion
var app = builder.Build();
...
app.Run();
}
3.2 在辅助角色项目中添加
辅助角色项目、MAUI项目等使用TouchSocket.Hosting
、TouchSocketPro.Hosting
。
- NET6.0
- NET8.0+
public static void Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
#region 添加Tcp服务器
services.AddTcpService(config =>
{
config.SetListenIPHosts(7789);
});
#endregion
services.AddHostedService<Worker>();
})
.Build();
host.Run();
}
public static void Main(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<Worker>();
#region 添加Tcp服务器
builder.Services.AddTcpService(config =>
{
config.SetListenIPHosts(7789);
});
#endregion
var host = builder.Build();
host.Run();
}
3.3 添加自定义服务器
通过上述的方式添加的服务器,会使用固定的接口作为注册类型。例如:通过默认的AddTcpService
来添加服务器,则会使用ITcpService
作为注册类型。
所以当想要添加两个服务器时,由于容器问题,第二个就会把第一个覆盖掉。所以就需要重新实现一个ITcpService
接口,来添加自定义的服务器。
例如:
我们可以先需要声明一个接口IMyTcpService
,继承自ITcpService
接口,然后声明自定义类MyTcpService
,继承TcpService
,同时实现IMyTcpService
。
class MyTcpService : TcpService, IMyTcpService
{
}
interface IMyTcpService : ITcpService
{
}
然后调用AddTcpService
泛型注册即可。
services.AddTcpService<IMyTcpService, MyTcpService>(config =>
{
config.SetListenIPHosts(7790);
});
这里可以使用AddTcpService
泛型注册的原因是MyTcpService
是TcpService
的派生类。如果不是,则需要使用AddServiceHostedService
来注册。
3.4 添加其他生命周期的服务
默认情况下,框架内提供的所有IService类的注册服务(即:AddServiceHostedService
),都是单例注册。且生命周期跟随整个Host。当Host启动时,所有注册的服务都会被创建。并且也会调用Start。当Host关闭时,所有注册的服务都会被销毁(当然可以提前注销,但是无法控制Start)。
但有的时候,我们需要将一个服务注册为瞬态,然后自己完全管理生命周期。那么我们可以通过下列方式来实现。
- AddSingletonSetupConfigObject:单例
- AddTransientSetupConfigObject:瞬态
- AddScopedSetupConfigObject:区域
public static void Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
//添加瞬态Tcp服务器。
//瞬态服务器,在host启动时,不会自己start,需要手动调用
services.AddTransientSetupConfigObject<ITcpService,TcpService>(config =>
{
config.SetListenIPHosts(7789);
});
services.AddHostedService<Worker>();
})
.Build();
host.Run();
}
通过这三中方式直接注册的服务,在Host启动时,不会自动调用Start。所以需要自己手动调用。
四、添加客户端类
一些常用的客户端组件,都已经被封装了,可以直接使用。例如:
- TcpClient
- TcpDmtpClient(由TouchSocket.AspNetCore提供)
没被封装的组件只是没直接提供扩展方法,而不是不能使用。具体操作请看下文。
4.1 添加TcpClient
客户端类的添加,和上面服务类的添加,基本一致。只不过默认就区分了瞬态、单例等注册方式。
public static void Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddTransientTcpClient(config =>
{
config.SetRemoteIPHost("127.0.0.1:7789");
});
services.AddHostedService<Worker>();
})
.Build();
host.Run();
}
客户端类的服务,在Host启动时,不会自动调用Connect。所以需要自己手动调用。
五、添加没有预设的服务
实际上所有的组件,都可以通过下列方法注册:
- AddSingletonSetupConfigObject:单例
- AddTransientSetupConfigObject:瞬态
- AddScopedSetupConfigObject:区域
但是对于服务器类的,可以根据其继承类,来选择更贴切的服务器注册。这样 就不用自己管理生命周期。
例如:对于TcpDmtpService。他是继承自TcpService,所以也可以直接使用AddTcpService泛型来注册。
public static void Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddTcpService<ITcpDmtpService, TcpDmtpService>(config =>
{
config.SetListenIPHosts(8848);
});
})
.Build();
host.Run();
}