跨服 API CrossServerAPI、CrossServerChannel、CrossServerEnvelope、CrossServerDelivery 统一跨服 SDK 参考。
Suite 提供统一跨服传输 API(Redis + BungeeCord Forward 双后端、统一信封)。模块通过 ModuleContext.crossServer() 获取实例,无需自行连接 Redis 或注册 BungeeCord 频道。
统一跨服传输入口。标记为 @ApiStability.Stable,永不为 null。
获取方式: context.crossServer()
CrossServerAPI crossServer = context. crossServer ();
方法 返回类型 说明 nodeId()String当前子服节点 id(来自宿主 cross-server.node-id) openChannel(moduleId, config, consumer)CrossServerChannel注册模块跨服通道
注册模块跨服通道。重复 openChannel 同 moduleId 会先关闭旧通道。
CrossServerChannel channel = crossServer. openChannel (
"mymodule" , // 模块 id
CrossServerChannelConfigs. fromSection ( // 通道配置
config. getConfigurationSection ( "cross-server" )
),
delivery -> Bukkit. getScheduler (). runTask (plugin, () -> // 入站回调(已在主线程调度)
handlePayload (delivery. payload ())
)
);
参数 说明 moduleId模块 id,写入信封 module 字段 config模块级开关(CrossServerChannelConfig) consumer入站消息回调(已在主线程调度)
模块跨服发布通道句柄。实现 AutoCloseable。
public interface CrossServerChannel extends AutoCloseable {
String moduleId ();
boolean isActive ();
void publish (String payload );
@ Override void close ();
}
方法 说明 moduleId()模块 id isActive()至少一种后端(Redis / Proxy)已成功启动 publish(payload)发布跨服消息;宿主负责封装信封与双后端发送 close()关闭通道
CrossServerChannel channel = crossServer. openChannel (
"mymodule" ,
CrossServerChannelConfig. enabledDefault (),
delivery -> {
// 处理来自其他子服的消息
logger. info ( "收到来自 " + delivery. nodeId () + " 的消息: " + delivery. payload ());
}
);
if (channel. isActive ()) {
channel. publish ( "hello-from-" + crossServer. nodeId ());
}
// 模块 onDisable 时关闭
channel. close ();
模块级跨服通道配置。连接参数由宿主 config.yml 统一管理。
public record CrossServerChannelConfig (
boolean enabled, // 模块是否启用跨服
Boolean redisEnabled, // 是否走 Redis;null 表示继承宿主全局开关
Boolean proxyEnabled // 是否走 Proxy Forward;null 表示继承宿主全局开关
) {
public static CrossServerChannelConfig enabledDefault ();
public static CrossServerChannelConfig disabled ();
}
CrossServerChannelConfig config =
CrossServerChannelConfigs. fromSection (
yamlConfig. getConfigurationSection ( "cross-server" )
);
模块 YAML 配置示例:
cross-server :
enabled : true
redis :
enabled : true # 可选,不写则继承全局
proxy :
enabled : false # 可选
跨服统一 wire 信封(JSON 序列化)。宿主负责封装,模块无需直接构造。
public record CrossServerEnvelope (
int protocol, // 协议版本(当前为 1)
String module, // 模块 id
String nodeId, // 来源子服节点 id
String messageId, // 消息唯一 id(UUID)
long timestamp, // 时间戳
String payload // 模块自定义 payload 字符串
) {
public static final int PROTOCOL_VERSION = 1 ;
}
经宿主跨服层去重后投递给模块的消息。
public record CrossServerDelivery (
String moduleId, // 模块 id(如 "tab"、"chat")
String nodeId, // 来源子服节点 id
String messageId, // 信封 message-id(UUID)
String payload // 模块自定义 payload 字符串
) {}
模块在 openChannel 的回调中接收此对象,通过 payload() 获取其他子服发来的数据。
public class MyModule extends AbstractAXSModule {
private CrossServerChannel channel;
@ Override
protected void startService () throws Exception {
CrossServerAPI crossServer = this .crossServer;
channel = crossServer. openChannel (
"mymodule" ,
CrossServerChannelConfigs. fromSection (
config. getSection ( "cross-server" )
),
delivery -> {
// 处理入站消息
handleRemoteMessage (delivery. payload (), delivery. nodeId ());
}
);
if (channel. isActive ()) {
logger. info ( "跨服通道已激活,节点: " + crossServer. nodeId ());
} else {
logger. warning ( "跨服通道未激活(Redis/Proxy 均不可用)" );
}
}
@ Override
protected void stopService () {
if (channel != null ) {
channel. close ();
channel = null ;
}
}
// 向其他子服广播消息
public void broadcast (String message ) {
if (channel != null && channel. isActive ()) {
channel. publish (message);
}
}
}
入站回调已在主线程调度,无需自行切换线程
payload 为字符串类型,模块可自行约定 JSON / YAML 等格式
宿主负责消息去重,模块无需关心重复投递
close() 应在模块 stopService() 中调用,避免通道泄漏