Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
若汝棋茗
RRQMSocket
比较版本
92df955ca288cefa84e83d6736a065d511d146f0...5e8cc4e4bcde35d3b93dc9a6bd09c71e14ee9a6f
RRQMSocket
项目概览
若汝棋茗
/
RRQMSocket
9 个月 前同步成功
通知
20
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
RRQMSocket
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
源分支
5e8cc4e4bcde35d3b93dc9a6bd09c71e14ee9a6f
选择Git版本
...
目标分支
92df955ca288cefa84e83d6736a065d511d146f0
选择Git版本
比较
Commits (9)
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/b8c779166cd9faf038c1ed17e4b9a77b49bdc0dd
修复示例demo
2023-05-29T19:57:32+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/46459aceaa18e35acc4b5ecd21e01f34d69ac02b
更新demo
2023-05-31T13:08:58+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/5066469901ec6a3720fb4b7cc1f5cc7038e9d676
添加cookie示例
2023-06-21T10:01:55+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/fba8ba0a9e149e08ce3be008572a5770879ac8bd
更新tcp服务器的创建
2023-06-23T23:42:35+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/543bdc0337a431832b270e2d1f4a2f3249f9be8f
增加动态添加、移除监听配置 文档
2023-06-23T23:59:03+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/60a762165aeb2c80493f909f51db6c8da2a23b33
更新waitingclient
2023-06-24T22:24:45+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/d070bc4acc7512c176163a369f2e2b4c467f9857
更新resetid文档
2023-06-24T22:30:31+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/b985b31891e52e0b689683873ef44d1a685d7e00
更新文档
2023-06-24T23:59:25+08:00
若汝棋茗
505554090@qq.com
https://gitcode.net/qq_40374647/RRQMSocket/-/commit/5e8cc4e4bcde35d3b93dc9a6bd09c71e14ee9a6f
更新demo
2023-07-04T16:33:39+08:00
若汝棋茗
505554090@qq.com
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
337 addition
and
231 deletion
+337
-231
examples/TouchRpc简单示例/TouchRpcClientApp/Form1.cs
examples/TouchRpc简单示例/TouchRpcClientApp/Form1.cs
+0
-1
examples/TouchRpc简单示例/推荐用法/RpcClassLibrary/ServerInterface/IUserServer.cs
...c简单示例/推荐用法/RpcClassLibrary/ServerInterface/IUserServer.cs
+4
-4
examples/WebSocket简单示例/WSFormClientApp/Form1.cs
examples/WebSocket简单示例/WSFormClientApp/Form1.cs
+7
-0
examples/WebSocket简单示例/WebSocketConsoleApp/Program.cs
examples/WebSocket简单示例/WebSocketConsoleApp/Program.cs
+7
-0
handbook/docs/createtcpclient.mdx
handbook/docs/createtcpclient.mdx
+94
-80
handbook/docs/createtcpservice.mdx
handbook/docs/createtcpservice.mdx
+165
-118
handbook/docs/resetid.mdx
handbook/docs/resetid.mdx
+20
-19
handbook/docs/tcpcommonplugins.mdx
handbook/docs/tcpcommonplugins.mdx
+4
-0
handbook/docs/upgrade.mdx
handbook/docs/upgrade.mdx
+16
-0
handbook/docs/waitingclient.mdx
handbook/docs/waitingclient.mdx
+19
-8
handbook/src/components/Tag.js
handbook/src/components/Tag.js
+1
-1
未找到文件。
examples/TouchRpc简单示例/TouchRpcClientApp/Form1.cs
浏览文件 @
5e8cc4e4
...
...
@@ -27,7 +27,6 @@ namespace TouchRpcClientApp
//后续参数为调用参数。
bool
result
=
client
.
Invoke
<
bool
>(
"touchrpcserverapp.myrpcserver.login"
,
InvokeOption
.
WaitInvoke
,
textBox1
.
Text
,
textBox2
.
Text
);
MessageBox
.
Show
(
result
.
ToString
());
client
.
SafeDispose
();
//client是长连接,可以复用,但在此处使用短连接。
}
...
...
examples/TouchRpc简单示例/推荐用法/RpcClassLibrary/ServerInterface/IUserServer.cs
浏览文件 @
5e8cc4e4
...
...
@@ -10,11 +10,11 @@ namespace RpcClassLibrary.ServerInterface
/// <summary>
/// 定义服务接口。
/// </summary>
[
GeneratorRpcProxy
(
Prefix
=
"RpcClassLibrary"
,
MethodFlags
=
MethodFlags
.
IncludeCallContext
)]
public
interface
IUserServer
:
IRpcServer
[
GeneratorRpcProxy
(
MethodFlags
=
MethodFlags
.
IncludeCallContext
)]
public
interface
IUserServer
:
IRpcServer
{
[
GeneratorRpcMethod
]
[
TouchRpc
]
LoginResponse
Login
(
ICallContext
callContext
,
LoginRequest
request
);
[
TouchRpc
(
MethodFlags
=
MethodFlags
.
IncludeCallContext
)
]
LoginResponse
Login
(
ICallContext
callContext
,
LoginRequest
request
);
}
}
examples/WebSocket简单示例/WSFormClientApp/Form1.cs
浏览文件 @
5e8cc4e4
...
...
@@ -167,5 +167,11 @@ namespace WSClientApp
break
;
}
}
protected
override
void
OnHandshaking
(
WebSocketClient
client
,
HttpContextEventArgs
e
)
{
e
.
Context
.
Request
.
Headers
[
"cookie"
]
=
""
;
base
.
OnHandshaking
(
client
,
e
);
}
}
}
\ No newline at end of file
examples/WebSocket简单示例/WebSocketConsoleApp/Program.cs
浏览文件 @
5e8cc4e4
...
...
@@ -54,6 +54,13 @@ namespace WebSocketConsoleApp
case
WSDataType
.
Text
:
Console
.
WriteLine
(
e
.
DataFrame
.
ToText
());
((
HttpSocketClient
)
client
).
SendWithWS
(
e
.
DataFrame
.
ToText
());
//using (ByteBlock byteBlock=new ByteBlock(1024*64))//估算一下你的数据大小
//{
// WSDataFrame dataFrame = new WSDataFrame();
// dataFrame.BuildResponse(byteBlock);
// ((HttpSocketClient)client).SendWithWS(byteBlock);
//}
break
;
case
WSDataType
.
Binary
:
...
...
handbook/docs/createtcpclient.mdx
浏览文件 @
5e8cc4e4
...
...
@@ -3,6 +3,7 @@ id: createtcpclient
title: 创建TcpClient
---
import Tag from "@site/src/components/Tag.js";
## 一、说明
...
...
@@ -41,56 +42,14 @@ TcpClient是Tcp系客户端基类,他直接参与tcp的连接、发送、接
数据包最大值(单位:byte),默认1024×1024×10。该值会在适当时间,直接作用DataHandlingAdapter.MaxPackageSize。
#### SetThreadCount
多线程数量。该值在Auto模式下指示线程池的最少线程数量和IO线程数量。
设置建议:
1. 异步处理接收数据,此时线程数量设置为内核线程左右的值即可。
2. 同步处理接收数据,此时应当考虑两个因素。该操作是否为耗时操作,如果是,则该值在允许范围内,应当设置更可能大的值。如果不是,则设置为内核线程左右的值即可。
#### SetGetDefaultNewID
配置初始ID的分配策略
#### SetListenIPHosts
监听IP和端口号组,可以一次性设置多个地址。
#### SetServerName
服务器标识名称,无实际使用意义。
#### SetBacklogProperty
Tcp半连接挂起连接队列的最大长度。默认为30
#### SetMaxCount
最大可连接数,默认为10000
#### SetReceiveType
接收类型。
- AUTO:自动接收模式。
- None:不投递IO接收申请,用户可通过GetStream,获取到流以后,自己处理接收。注意:连接端不会感知主动断开。
#### UsePlugin
是否启用插件。在启用时或许会带来一点点性能损耗,基本上不是千万数据交互根本不值一提。
#### SetServiceSslOption
Ssl配置,为Null时则不启用。
#### UseNoDelay
设置Socket的NoDelay属性,默认false。
#### UseDelaySender
使用延迟发送。众所周知,tcp数据报文为了发送效率,会默认启用**延迟算法**。但是这种设置,只能一定程度的缓解小数据发送效率低的问题,因为它为了保证多线程发送的有序性,在send函数中设置了线程同步,所以说,每调用一次send,实际上都是巨大的性能消耗(此处用iocp发送亦然)。所以,要解决该问题, 最终还是要将小数据,组合成大数据,这样才能更高效率的发送。所以,DelaySender正是负责此类工作的。
使用DelaySender,会一定程度的降低发送的及时性,但是降低程度并不高,简单来说:
1. 如果一个包大于512kb,则不会延迟,直接发送。
2. 如果发送第一个包,与第二个包的时间间隔小于一个线程池线程调度的时间(这个时间极短,一般来说会在10**微秒**左右),则会将这两个包压缩为一个包发送。
#### UseReuseAddress
启用端口复用。该配置可在服务器、或客户端在监听端口时,运行监听同一个端口。可以一定程度缓解端口来不及释放的问题。
#### SetRemoteIPHost
链接到的远程IPHost,支持域名。支持类型:
...
...
@@ -121,54 +80,102 @@ Ssl配置,为Null时则不启用。
#### UseNoDelay
设置Socket的NoDelay属性,默认false。
#### UseBroadcast
该值指定可以发送或接收广播数据包。
</div>
</details>
## 五、支持插件
支持**ITcpPlugin**接口,或者继承自**TcpPluginBase**类,重写相应方法即可。
| 插件方法| 功能 |
| --- | --- |
| OnConnecting | 在Socket完成初始化,但是并未连接时触发。 |
| OnConnected | 在Socket完成连接,且成功后触发 |
| OnDisconnecting | 当客户端主动调用Close时触发 |
| OnDisconnected | 当客户端断开连接后触发 |
| OnReceivingData | 在收到原始数据时触发,所有的数据均在ByteBlock里面。 |
| OnReceivedData | 在收到适配器数据时触发,根据适配器类型,数据可能在ByteBlock或者IRequestInfo里面。 |
| OnSendingData | 当即将发送数据时,调用该方法在适配器之后,接下来即会发送数据。 |
| ITcpConnectingPlugin | 此时Socket实际上已经完成连接,但是并没有启动接收,然后触发。 |
| ITcpConnectedPlugin | 同意连接,且成功启动接收后触发 |
| ITcpDisconnectingPlugin | 当客户端主动调用Close时触发 |
| ITcpDisconnectedPlugin | 当客户端断开连接后触发 |
| ITcpReceivingPlugin | 在收到原始数据时触发,所有的数据均在ByteBlock里面。 |
| ITcpReceivedPlugin | 在收到适配器数据时触发,根据适配器类型,数据可能在ByteBlock或者IRequestInfo里面。 |
| ITcpSendingPlugin | 当即将发送数据时,调用该方法在适配器之后,接下来即会发送数据。 |
| IIdChangedPlugin | 当SocketClient的ID发生改变时触发。 |
## 六、创建TcpClient
#### 6.1 简单创建
简单的处理逻辑可通过**Connecting**、**Connected**、**Received**等委托直接实现。
代码如下:
```csharp
TcpClient tcpClient = new TcpClient();
tcpClient.Connected += (client, e) => { };//成功连接到服务器
tcpClient.Disconnected += (client, e) => { };//从服务器断开连接,当连接不成功时不会触发。
tcpClient.Received += (client, byteBlock, requestInfo) =>
tcpClient.Connecting = (client, e) => { };//即将连接到服务器,此时已经创建socket,但是还未建立tcp
tcpClient.Connected = (client, e) => { };//成功连接到服务器
tcpClient.Disconnecting = (client, e) => { };//即将从服务器断开连接。此处仅主动断开才有效。
tcpClient.Disconnected = (client, e) => { };//从服务器断开连接,当连接不成功时不会触发。
tcpClient.Received = (client, byteBlock, requestInfo) =>
{
//从服务器收到信息
//从服务器收到信息
。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
string mes = Encoding.UTF8.GetString(byteBlock.Buffer, 0, byteBlock.Len);
Console.WriteLine($"
接收到信息:{mes}");
tcpClient.Logger.Info($"客户端
接收到信息:{mes}");
};
//声明配置
TouchSocketConfig config = new TouchSocketConfig();
config.SetRemoteIPHost(new IPHost("127.0.0.1:7789"))
.UsePlugin();
//载入配置
tcpClient.Setup(config);
tcpClient.Connect();
tcpClient.Setup(new TouchSocketConfig()
.SetRemoteIPHost("127.0.0.1:7789")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();//添加一个日志注入
}));
tcpClient.Connect();//调用连接,当连接不成功时,会抛出异常。
//Result result = tcpClient.TryConnect();//或者可以调用TryConnect
//if (result.IsSuccess())
//{
//}
tcpClient.Logger.Info("客户端成功连接");
tcpClient.Send("RRQM");
```
#### 6.2 继承实现
一般继承实现的话,可以从TcpClientBase继承。
```csharp
class MyTcpClient: TcpClientBase
{
protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
//此处逻辑单线程处理。
//此处处理数据,功能相当于Received委托。
string mes = Encoding.UTF8.GetString(byteBlock.Buffer, 0, byteBlock.Len);
Console.WriteLine($"已接收到信息:{mes}");
return true;//返回true,则表示该数据已被当前处理。不会再触发后续的插件等。
}
}
```
```csharp
MyTcpClient tcpClient = new MyTcpClient();
tcpClient.Connecting = (client, e) => { };//即将连接到服务器,此时已经创建socket,但是还未建立tcp
tcpClient.Connected = (client, e) => { };//成功连接到服务器
tcpClient.Disconnecting = (client, e) => { };//即将从服务器断开连接。此处仅主动断开才有效。
tcpClient.Disconnected = (client, e) => { };//从服务器断开连接,当连接不成功时不会触发。
//载入配置
tcpClient.Setup(new TouchSocketConfig()
.SetRemoteIPHost("127.0.0.1:7789")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();//添加一个日志注入
}));
tcpClient.Connect();//调用连接,当连接不成功时,会抛出异常。
```
## 七、接收数据
在TcpClient中,接收数据的方式有很多种。多种方式可以组合使用。
...
...
@@ -196,27 +203,25 @@ tcpClient.Setup(config);
tcpClient.Connect();
```
### 7.2 插件处理
推荐
### 7.2 插件处理
<Tag>推荐</Tag>
按照TouchSocket的设计理念,使用插件处理数据,是一项非常简单,且高度解耦的方式。步骤如下:
1. 服务器配置启用插件(UsePlugin)
2. 新建插件类
3. 添加插件
(1)声明插件
代码如下:
插件可以先继承`PluginBase`,然后再实现需要的功能插件接口,可以按需选择泛型或者非泛型实现。
(1)声明插件
如果已经有继承类,直接实现`IPlugin`接口即可。
```csharp
public class MyPlugin :
TcpPluginBase
<TcpClient>
public class MyPlugin :
PluginBase,ITcpReceivedPlugin
<TcpClient>
{
public MyPlugin()
{
this.Order = 0;//此值表示插件的执行顺序,当多个插件并存时,该值越大,越在前执行。
}
p
rotected override void OnReceivedData
(TcpClient client, ReceivedDataEventArgs e)
p
ublic void OnTcpReceived
(TcpClient client, ReceivedDataEventArgs e)
{
//这里处理数据接收
//根据适配器类型,e.ByteBlock与e.RequestInfo会呈现不同的值,具体看文档=》适配器部分。
...
...
@@ -224,7 +229,11 @@ public class MyPlugin : TcpPluginBase<TcpClient>
IRequestInfo requestInfo = e.RequestInfo;
//e.Handled = true;//表示该数据已经被本插件处理,无需再投递到其他插件。
base.OnReceivedData(client, e);
}
public Task OnTcpReceivedAsync(TcpClient client, ReceivedDataEventArgs e)
{
return Task.CompletedTask;
}
}
```
...
...
@@ -234,13 +243,12 @@ public class MyPlugin : TcpPluginBase<TcpClient>
```csharp
TcpClient client = new TcpClient();
client.Setup(new TouchSocketConfig()
.SetRemoteIPHost(new IPHost("127.0.0.1:7789"))
.UsePlugin()
.ConfigureContainer(a=>
.SetRemoteIPHost("127.0.0.1:7789")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();
})
.ConfigurePlugins(a =>
.ConfigurePlugins(a =>
{
a.Add<MyPlugin>();
}))
...
...
@@ -268,3 +276,9 @@ public virtual Task SendAsync(byte[] buffer);
public virtual Task SendAsync(byte[] buffer, int offset, int length);
```
:::tip 提示
框架不仅内置了`Send`字节的发送,也扩展了字符串等常见数据的发送。而且还包括了`TrySend`等不会抛出异常的发送方法。
:::
handbook/docs/createtcpservice.mdx
浏览文件 @
5e8cc4e4
此差异已折叠。
点击以展开。
handbook/docs/resetid.mdx
浏览文件 @
5e8cc4e4
---
id: resetid
title: 服务器重置
ID
title: 服务器重置
id
---
## 一、说明
每个客户端在连接时,服务器都会为连接的客户端**新分配**一个唯一的I
D。也就是说,在服务器中ID
与SocketClient实例就是一一对应的。
每个客户端在连接时,服务器都会为连接的客户端**新分配**一个唯一的I
d。也就是说,在服务器中Id
与SocketClient实例就是一一对应的。
## 二、配置初始I
D
策略
## 二、配置初始I
d
策略
默认情况下服务器都会根据**历史连接数量**,为连接的客户端新分配I
D。也就是说,第一个连接的,其ID
就是1,以此类推。
默认情况下服务器都会根据**历史连接数量**,为连接的客户端新分配I
d。也就是说,第一个连接的,其Id
就是1,以此类推。
当然我们可以自由的定义I
D策略,只需要在Config配置中,配置[SetGetDefaultNewID](../docs/createtcpservice.mdx#setgetdefaultnewid),自定义新ID来源即可。要求不和现连接的客户端ID
重复。
当然我们可以自由的定义I
d策略,只需要在Config配置中,配置[SetGetDefaultNewId](../docs/createtcpservice.mdx#setgetdefaultnewid),自定义新id来源即可。要求不和现连接的客户端id
重复。
下列示例,就是使用Guid作为初始I
D
。
下列示例,就是使用Guid作为初始I
d
。
```csharp
.SetGetDefaultNewID(()=> { return new Guid().ToString(); })
var config = new TouchSocketConfig();
config.SetGetDefaultNewId(()=>Guid.NewGuid().ToString());
```
## 三、创建能代表连接的I
D
## 三、创建能代表连接的I
d
上述这种I
D
规范,是与连接信息没有任何关联的,这也就意味着,这种方式是无法关联SocketClient的。
上述这种I
d
规范,是与连接信息没有任何关联的,这也就意味着,这种方式是无法关联SocketClient的。
但往往,有时候,我们希望,SocketClient的I
D,能一定程度的代表一些信息。例如:以客户端的IP和端口,作为唯一ID
。
但往往,有时候,我们希望,SocketClient的I
d,能一定程度的代表一些信息。例如:以客户端的IP和端口,作为唯一id
。
那这时候,**服务器**可以订阅**Connecting**,然后,为新连接的SocketClient,设置与之有关联信息的
ID
。
那这时候,**服务器**可以订阅**Connecting**,然后,为新连接的SocketClient,设置与之有关联信息的
id
。
```csharp
m_service.Connecting = (client, e) =>
m_service.Connecting = (client, e) =>
//有客户端正在连接
{
e.I
D
= $"{client.IP}:{client.Port}";
};
//有客户端正在连接
e.I
d
= $"{client.IP}:{client.Port}";
};
```
:::tip 提示
...
...
@@ -40,23 +41,23 @@ m_service.Connecting = (client, e) =>
:::
## 四、即时修改
ID
## 四、即时修改
id
上述修改I
D的方式,应该还不足以应对所有情况。有时候我们希望,在该连接完成,且经过某种验证之后再设置新的ID,那么我们可以通过**ResetID
**的方法,来实现需求。
上述修改I
d的方式,应该还不足以应对所有情况。有时候我们希望,在该连接完成,且经过某种验证之后再设置新的id,那么我们可以通过**ResetId
**的方法,来实现需求。
### 4.1 通过Service直接修改
```csharp
service.ResetI
D
("oldId","newId");
service.ResetI
d
("oldId","newId");
```
### 4.2 通过SocketClient修改
```csharp
socketClient.ResetI
D
("newId");
socketClient.ResetI
d
("newId");
```
:::note 备注
上述的I
D
标识,仅仅是服务器(TcpService)和辅助客户端(SocketClient)之间的关联。与客户端(TcpClient)是没有任何关系的。
上述的I
d
标识,仅仅是服务器(TcpService)和辅助客户端(SocketClient)之间的关联。与客户端(TcpClient)是没有任何关系的。
:::
\ No newline at end of file
handbook/docs/tcpcommonplugins.mdx
0 → 100644
浏览文件 @
5e8cc4e4
---
id: tcpcommonplugins
title: 常用插件
---
\ No newline at end of file
handbook/docs/upgrade.mdx
浏览文件 @
5e8cc4e4
...
...
@@ -18,6 +18,22 @@ import Tag from "@site/src/components/Tag.js";
:::
## v1.5
更新日期:未定
更新描述:大版本更新。
- <Tag>优化</Tag> FileLogger支持指定不同目录。
- <Tag>优化</Tag> IPHost支持从int、string直接隐式转换。
- <Tag>调整</Tag> TouchSocket所有“ID”属性,改名为“Id”。
- <Tag>调整</Tag> TouchSocket所有插件的执行顺序,移动至内部重写方法之后。
- <Tag>调整</Tag> TouchSocket所有`ResetID`改名为`ResetId`。
- <Tag>移除</Tag> UsePlugin的显式配置,当调用ConfigurePlugins时,会自动启用。
- <Tag>新增</Tag> ws协议的TouchRpc服务端,增加HttpContext上下文获取。
---
## v1.3
更新日期:2023.3.1
...
...
handbook/docs/waitingclient.mdx
浏览文件 @
5e8cc4e4
...
...
@@ -17,20 +17,23 @@ title: 同步请求
### 2.1 以TcpClient为例
```csharp
TcpClient m_tcpClient = new TcpClient();
var config = new TouchSocketConfig();
config.SetRemoteIPHost(new IPHost("127.0.0.1:7789"));
//载入配置
m_tcpClient.Setup(config);
m_tcpClient.Connect();
TcpClient client = new TcpClient();
client.Connect("127.0.0.1:7789");
//调用GetWaitingClient获取到IWaitingClient的对象。
var waitClient =
m_tcpC
lient.GetWaitingClient(new WaitingOptions()
var waitClient =
c
lient.GetWaitingClient(new WaitingOptions()
{
AdapterFilter = AdapterFilter.AllAdapter,//表示发送和接收的数据都会经过适配器
BreakTrigger = true,//表示当连接断开时,会立即触发
ThrowBreakException = true//表示当连接断开时,是否触发异常
},
response => //设置用于筛选的fun委托,当返回为true时,才会响应返回
{
if (response.Data.Length==1)
{
return true;
}
return false;
});
//然后使用SendThenReturn。
...
...
@@ -54,6 +57,14 @@ service.Received = (client, byteBlock, requestInfo) =>
AdapterFilter = AdapterFilter.AllAdapter,//表示发送和接收的数据都会经过适配器
BreakTrigger = true,//表示当连接断开时,会立即触发
ThrowBreakException = true//表示当连接断开时,是否触发异常
},
response => //设置用于筛选的fun委托,当返回为true时,才会响应返回
{
if (response.Data.Length==1)
{
return true;
}
return false;
});
//然后使用SendThenReturn。
...
...
handbook/src/components/Tag.js
浏览文件 @
5e8cc4e4
...
...
@@ -31,7 +31,7 @@ export default function (props) {
},
移除
:
{
icon
:
"
shanchu
"
,
bgColor
:
"
#666
"
,
bgColor
:
"
red
"
,
},
答疑
:
{
icon
:
"
dayi
"
,
...
...