反向 WebSocket
反向 WebSocket 是实现和使用最复杂的一种方式。考虑到反向 WebSocket 的潜在使用场景,WudiLib 会在建立连接后再配置 Listener。
目前 WudiLib 只支持“Universe”连接类型,也就是 API 和事件都用一个连接。
快速上手
要使用反向 WebSocket,请引入 Sisters.WudiLib.WebSocket 包不低于 0.2.0-beta3 的版本。然后在 Main
方法中编写以下代码:
using Sisters.WudiLib.WebSocket.Reverse;
var reverseWSServer = new ReverseWebSocketServer("http://localhost:9191");
reverseWSServer.SetListenerAuthenticationAndConfiguration((listener, selfId) =>
{
listener.MessageEvent += (api, e) =>
{
Console.WriteLine(e.Content.Text);
};
});
reverseWSServer.Start();
编写好之后运行程序,然后用 OneBot 服务(如 go-cqhttp)反向 WS 连接到 localhost:9191,之后可以看到,当 bot 每收到一条消息,就会把文本部分打印到控制台上。
进阶反向 WebSocket
传入 SetListenerAuthenticationAndConfiguration
方法的委托会在有连接来临时调用,每次调用都会构造新的 Listener 和 API 客户端,一旦连接断开,则不能再使用。
当你需要外部使用构造的 Listener 或 API 客户端时,可以在委托里传给外界。例如:
var reverseWSServer = new ReverseWebSocketServer("http://localhost:9191");
HttpApiClient onebotApi = null;
reverseWSServer.SetListenerAuthenticationAndConfiguration((listener, selfId) =>
{
onebotApi = listener.ApiClient; // 当建立反向 WebSocket 连接时,把 API 客户端赋值到外面。
listener.SocketDisconnected += () => onebotApi = null; // 连接断开时已无法使用,把 API 客户端设为 null。
});
reverseWSServer.Start();
while (true)
{
// 每 1 分钟尝试发送一次群组消息。
await Task.Delay(60000);
var api = onebotApi;
if (api != null)
{
try
{
await onebotApi.SendGroupMessageAsync(1234567, "Hello");
}
catch (Exception)
{
// 记录日志等。
}
}
}
注意
上面的示例假定同时只有一个反向 WebSocket 连接,如果建立了多个连接则会出问题。WudiLib 支持同时建立多个反向 WebSocket 连接,将在文档后半讲述用法。
提示
配置时可以查看 selfId
,并根据 selfId
进行不同的配置(例如注册不同的事件处理器)。
鉴权认证
WudiLib 支持对反向 WebSocket 连接进行认证,并内置了通过 Access Token 和/或 Self ID(即机器人 QQ 号)进行认证。
要进行鉴权认证,只需要在配置方法中添加 Access Token 和 Self ID 两个参数即可。
var reverseWSServer = new ReverseWebSocketServer("http://localhost:9191");
reverseWSServer.SetListenerAuthenticationAndConfiguration((listener, selfId) =>
{
// Configuration code.
}, "your-access-token", 123456789);
reverseWSServer.Start();
当按此鉴权时,只接受 QQ 为 123456789,并且 Access Token 配置为“your-access-token”的机器人连接。其中两个参数可以分别设置为 null
,表示跳过这一项,例如只验证 QQ 号或者 Access Token。
高级鉴权及配置
WudiLib 的强大之处在于,你可以自定义鉴权过程,并且根据不同的鉴权结果进行不同的配置。例如:
using System.Net;
var reverseWSServer = new ReverseWebSocketServer("http://localhost:9191");
HttpApiClient onebotApi = null;
reverseWSServer.SetListenerAuthenticationAndConfiguration(async request =>
{
IPAddress[] allowedIPAddress = await GetAllowedIPAddress();
if (allowedIPAddress.Contains(request.RemoteEndPoint.Address))
{
// allow
return (listener, selfId) =>
{
// Configuration code.
};
}
else
{
// deny
return null;
// Or you can return another configuration.
//return (listener, selfId) =>
//{
// // Configure for only basic functions.
//};
}
});
reverseWSServer.Start();
运行这段代码,WudiLib 会在收到连接时执行验证。如果连接的 IP 在允许列表中,就允许连接并进行配置;否则就拒绝连接(也可以进行另一种配置)。高级鉴权可以和简单鉴权结合使用,此时 WudiLib 会先验证 Access Token 和 Self ID 是否吻合,然后再执行自定义的认证和配置。
提示
进行自定义鉴证应传入一个异步委托,这是为了便于从数据库等地方读取认证信息。