---
id: generichost
title: 通用主机
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

### 定义

命名空间：TouchSocket.Hosting <br/>
程序集：[TouchSocket.Hosting.dll](https://www.nuget.org/packages/TouchSocket.Hosting)<br/>
程序集：[TouchSocketPro.Hosting.dll](https://www.nuget.org/packages/TouchSocketPro.Hosting)


## 一、说明

Hosting通用主机，是在创建一个[HostBuilder](https://learn.microsoft.com/zh-cn/dotnet/core/extensions/generic-host) 之后，可以通过Add的服务的形式创建`TouchSocket`的一些组件。如`TcpService`、`TcpClient`、`NamedPipeService`、`NamedPipeclient`等。


## 二、安装Nuget包

在安装Nuget之前，最好先确认目标项目是一个主机项目。例如：[辅助角色服务模板](https://learn.microsoft.com/zh-cn/dotnet/core/extensions/generic-host)、 [AspNetCore](https://learn.microsoft.com/zh-cn/aspnet/core)等。如果是其他项目，请自行解决依赖。

使用Nuget安装`TouchSocket.Hosting`、`TouchSocketPro.Hosting`、`TouchSocket.AspNetCore`、`TouchSocketPro.AspNetCore`其中的**任意一个**。

:::info 备注

`TouchSocket.Hosting`、`TouchSocketPro.Hosting`、`TouchSocket.AspNetCore`、`TouchSocketPro.AspNetCore`都可以安装使用。主要区别就是：Hosting的只包含基础扩展。AspNetCore的会对Web项目有更多扩展。

:::  

:::tip 建议

一般建议Web项目使用`TouchSocket.AspNetCore`、`TouchSocketPro.AspNetCore`。辅助角色项目、MAUI项目等使用`TouchSocket.Hosting`、`TouchSocketPro.Hosting`。

:::  

## 三、添加服务器类

一些常用的服务器组件，都已经被封装了，可以直接使用。例如：

- TcpService
- UdpService
- TcpDmtpService（由TouchSocket.AspNetCore提供）

:::info 备注

没被封装的组件只是没直接提供扩展方法，而不是不能使用。具体操作请看下文。

:::  

### 3.1 在Aspnetcore中添加

下列示例只配置了监听端口，更多配置请看[TcpService](./tcpservice.mdx)。

```csharp {7-12} showLineNumbers
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`。

<Tabs
    defaultValue="tab1"
    values=
    {[
        { label: "NET6.0",value: "tab1"},
        { label: "NET8.0+", value: "tab2" }
    ]}
>
<TabItem value="tab1">

```csharp {6-11} showLineNumbers
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();
}
```

</TabItem>
<TabItem value="tab2">

```csharp {5-10} showLineNumbers
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();
}

```
</TabItem>
</Tabs>

### 3.3 添加自定义服务器

通过上述的方式添加的服务器，会使用固定的接口作为注册类型。例如：通过默认的`AddTcpService`来添加服务器，则会使用`ITcpService`作为注册类型。

所以当想要添加两个服务器时，由于容器问题，第二个就会把第一个覆盖掉。所以就需要重新实现一个`ITcpService`接口，来添加自定义的服务器。

例如：

我们可以先需要声明一个接口`IMyTcpService`，继承自`ITcpService`接口，然后声明自定义类`MyTcpService`，继承`TcpService`，同时实现`IMyTcpService`。

```csharp showLineNumbers
class MyTcpService : TcpService, IMyTcpService
{

}

interface IMyTcpService : ITcpService
{

}
```

然后调用`AddTcpService`泛型注册即可。

```csharp showLineNumbers
services.AddTcpService<IMyTcpService, MyTcpService>(config =>
{
    config.SetListenIPHosts(7790);
});
```

:::info 备注

这里可以使用`AddTcpService`泛型注册的原因是`MyTcpService`是`TcpService`的派生类。如果不是，则需要使用`AddServiceHostedService`来注册。

:::  

### 3.4 添加其他生命周期的服务

默认情况下，框架内提供的所有IService类的注册服务（即：`AddServiceHostedService`），都是单例注册。且生命周期跟随整个Host。当Host启动时，所有注册的服务都会被创建。并且也会调用Start。当Host关闭时，所有注册的服务都会被销毁（当然可以提前注销，但是无法控制Start）。

但有的时候，我们需要将一个服务注册为瞬态，然后自己完全管理生命周期。那么我们可以通过下列方式来实现。

- AddSingletonSetupConfigObject：单例
- AddTransientSetupConfigObject：瞬态
- AddScopedSetupConfigObject：区域

```csharp {6-11} showLineNumbers
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();
}
```

:::tip 提示

通过这三中方式直接注册的服务，在Host启动时，不会自动调用Start。所以需要自己手动调用。

:::  


## 四、添加客户端类

一些常用的客户端组件，都已经被封装了，可以直接使用。例如：

- TcpClient
- TcpDmtpClient（由TouchSocket.AspNetCore提供）

:::info 备注

没被封装的组件只是没直接提供扩展方法，而不是不能使用。具体操作请看下文。

:::  

### 4.1 添加TcpClient

客户端类的添加，和上面服务类的添加，基本一致。只不过默认就区分了瞬态、单例等注册方式。

```csharp {6-9} showLineNumbers
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();
}
```

:::tip 提示

客户端类的服务，在Host启动时，不会自动调用Connect。所以需要自己手动调用。

:::  


## 五、添加没有预设的服务

实际上所有的组件，都可以通过下列方法注册：

- AddSingletonSetupConfigObject：单例
- AddTransientSetupConfigObject：瞬态
- AddScopedSetupConfigObject：区域

但是对于服务器类的，可以根据其继承类，来选择更贴切的服务器注册。这样就不用自己管理生命周期。

例如：对于TcpDmtpService。他是继承自TcpService，所以也可以直接使用AddTcpService**泛型**来注册。

```csharp {6-9} showLineNumbers
public static void Main(string[] args)
{
    IHost host = Host.CreateDefaultBuilder(args)
        .ConfigureServices(services =>
        {
            services.AddTcpService<ITcpDmtpService, TcpDmtpService>(config => 
            {
                config.SetListenIPHosts(8848);
            });
        })
        .Build();

    host.Run();
}
```

[本文示例Demo](https://gitee.com/RRQM_Home/TouchSocket/tree/master/examples_host/Examples.Host)