del[net]: delete SignalOnlyAttachment

This commit is contained in:
godotg
2023-09-10 13:20:04 +08:00
parent f923c0c14b
commit 94bb9ae7cb
7 changed files with 53 additions and 138 deletions
@@ -23,6 +23,7 @@ import com.zfoo.net.packet.common.Heartbeat;
import com.zfoo.net.packet.common.Ping;
import com.zfoo.net.packet.common.Pong;
import com.zfoo.net.router.attachment.GatewayAttachment;
import com.zfoo.net.router.attachment.SignalAttachment;
import com.zfoo.net.session.Session;
import com.zfoo.net.util.SessionUtils;
import com.zfoo.protocol.util.JsonUtils;
@@ -81,7 +82,7 @@ public class GatewayRouteHandler extends ServerRouteHandler {
// 把客户端信息包装为一个GatewayAttachment,因此通过这个网关附加包可以得到玩家的uid、sid之类的信息
var gatewayAttachment = new GatewayAttachment(session);
gatewayAttachment.wrapAttachment(decodedPacketInfo.getAttachment());
gatewayAttachment.setSignalAttachment((SignalAttachment) decodedPacketInfo.getAttachment());
// 网关优先使用IGatewayLoadBalancer作为一致性hash的计算参数,然后才会使用客户端的session做参数
// 例子:以聊天服务来说,玩家知道自己在哪个群组groupId中,那往这个群发送消息时,会在Packet中带上这个groupId做为一致性hash就可以了。
@@ -74,67 +74,69 @@ public class Router implements IRouter {
return;
}
if (attachment == null) {
// 正常发送消息的接收,把客户端的业务请求包装下到路由策略指定的线程进行业务处理
// 注意:像客户端以asyncAsk发送请求,在服务器处理完后返回结果,在请求方也是进入这个receive方法,但是attachment不为空,会提前return掉不会走到这
TaskBus.dispatch(new PacketReceiverTask(session, packet, null));
return;
}
// 发送者(客户端)同步和异步消息的接收,发送者通过signalId判断重复
if (attachment != null) {
if (attachment.getClass() == SignalAttachment.class) {
var signalAttachment = (SignalAttachment) attachment;
if (attachment.getClass() == SignalAttachment.class) {
var signalAttachment = (SignalAttachment) attachment;
if (signalAttachment.isClient()) {
// 服务器收到signalAttachment,不做任何处理
signalAttachment.setClient(false);
} else {
// 客户端收到服务器应答,客户端发送的时候isClient为true,服务器收到的时候将其设置为false
var removedAttachment = (SignalAttachment) SignalBridge.removeSignalAttachment(signalAttachment);
if (removedAttachment != null) {
// 这里会让之前的CompletableFuture得到结果,从而像asyncAsk之类的回调到结果
removedAttachment.getResponseFuture().complete(packet);
} else {
logger.error("client receives packet:[{}] and attachment:[{}] from server, but clientAttachmentMap has no attachment, perhaps timeout exception.", JsonUtils.object2String(packet), JsonUtils.object2String(attachment));
}
// 注意:这个return,这样子,asyncAsk的结果就返回了。
if (signalAttachment.isClient()) {
// 服务器收到signalAttachment,不做任何处理
signalAttachment.setClient(false);
TaskBus.dispatch(new PacketReceiverTask(session, packet, attachment));
} else {
// 客户端收到服务器应答,客户端发送的时候isClient为true,服务器收到的时候将其设置为false
var removedAttachment = (SignalAttachment) SignalBridge.removeSignalAttachment(signalAttachment);
if (removedAttachment == null) {
logger.error("client receives packet:[{}] and attachment:[{}] from server, but clientAttachmentMap has no attachment, perhaps timeout exception.", JsonUtils.object2String(packet), JsonUtils.object2String(attachment));
return;
}
} else if (attachment.getClass() == GatewayAttachment.class) {
var gatewayAttachment = (GatewayAttachment) attachment;
// 这里会让之前的CompletableFuture得到结果,从而像asyncAsk之类的回调到结果
removedAttachment.getResponseFuture().complete(packet);
}
return;
}
// 如:在网关监听到GatewaySessionInactiveEvent后,这时告诉home时,这个client参数设置的true
// 注意:此时并没有return,这样子网关的消息才能发给home,在home进行处理LogoutRequest消息的处理
if (gatewayAttachment.isClient()) {
gatewayAttachment.setClient(false);
} else {
// 这里是:别的服务提供者提供授权给网关,比如:在玩家登录后,home服查到了玩家uid,然后发给Gateway服
var gatewaySession = NetContext.getSessionManager().getServerSession(gatewayAttachment.getSid());
if (gatewaySession != null) {
var signalAttachmentInGatewayAttachment = gatewayAttachment.getSignalAttachment();
if (signalAttachmentInGatewayAttachment != null) {
signalAttachmentInGatewayAttachment.setClient(false);
}
if (attachment.getClass() == GatewayAttachment.class) {
var gatewayAttachment = (GatewayAttachment) attachment;
// 网关授权,授权完成直接返回
// 注意:这个 AuthUidToGatewayCheck 是在home的LoginController中处理完登录后,把消息发给网关进行授权
if (AuthUidToGatewayCheck.class == packet.getClass()) {
var uid = ((AuthUidToGatewayCheck) packet).getUid();
if (uid <= 0) {
logger.error("错误的网关授权信息,uid必须大于0");
return;
}
gatewaySession.setUid(uid);
EventBus.post(AuthUidToGatewayEvent.valueOf(gatewaySession.getSid(), uid));
// 如:在网关监听到GatewaySessionInactiveEvent后,这时告诉home时,这个client参数设置的true
// 注意:此时并没有return,这样子网关的消息才能发给home,在home进行处理LogoutRequest消息的处理
if (gatewayAttachment.isClient()) {
gatewayAttachment.setClient(false);
TaskBus.dispatch(new PacketReceiverTask(session, packet, attachment));
} else {
// 这里是:别的服务提供者提供授权给网关,比如:在玩家登录后,home服查到了玩家uid,然后发给Gateway服
var gatewaySession = NetContext.getSessionManager().getServerSession(gatewayAttachment.getSid());
if (gatewaySession == null) {
logger.warn("gateway receives packet:[{}] and attachment:[{}] from server" + ", but serverSessionMap has no session[id:{}], perhaps client disconnected from gateway.", JsonUtils.object2String(packet), JsonUtils.object2String(attachment), gatewayAttachment.getSid());
return;
}
NetContext.getRouter().send(session, AuthUidToGatewayConfirm.valueOf(uid), new GatewayAttachment(gatewaySession));
return;
}
send(gatewaySession, packet, gatewayAttachment.attachment());
} else {
logger.error("gateway receives packet:[{}] and attachment:[{}] from server" + ", but serverSessionMap has no session[id:{}], perhaps client disconnected from gateway.", JsonUtils.object2String(packet), JsonUtils.object2String(attachment), gatewayAttachment.getSid());
// 网关授权,授权完成直接返回
// 注意:这个 AuthUidToGatewayCheck 是在home的LoginController中处理完登录后,把消息发给网关进行授权
if (AuthUidToGatewayCheck.class == packet.getClass()) {
var uid = ((AuthUidToGatewayCheck) packet).getUid();
if (uid <= 0) {
logger.error("错误的网关授权信息,uid必须大于0");
return;
}
gatewaySession.setUid(uid);
EventBus.post(AuthUidToGatewayEvent.valueOf(gatewaySession.getSid(), uid));
NetContext.getRouter().send(session, AuthUidToGatewayConfirm.valueOf(uid), new GatewayAttachment(gatewaySession));
return;
}
send(gatewaySession, packet, gatewayAttachment.getSignalAttachment());
}
return;
}
// 正常发送消息的接收,把客户端的业务请求包装下到路由策略指定的线程进行业务处理
// 注意:像客户端以asyncAsk发送请求,在服务器处理完后返回结果,在请求方也是进入这个receive方法,但是attachment不为空,会提前return掉不会走到这
TaskBus.dispatch(new PacketReceiverTask(session, packet, attachment));
}
@@ -26,8 +26,6 @@ public enum AttachmentType {
*/
SIGNAL_PACKET(SignalAttachment.class),
SIGNAL_ONLY_PACKET(SignalOnlyAttachment.class),
/**
* gateway attachment
*/
@@ -49,7 +49,6 @@ public class GatewayAttachment {
* CN:客户端发到网关的可能是一个带有同步或者异步的附加包,网关转发的时候需要把这个附加包给带上
*/
private SignalAttachment signalAttachment;
private SignalOnlyAttachment signalOnlyAttachment;
public GatewayAttachment() {
@@ -80,28 +79,6 @@ public class GatewayAttachment {
this.taskExecutorHashParam = argument.hashCode();
}
public void wrapAttachment(Object attachment) {
if (attachment == null) {
return;
}
var attachmentClass = attachment.getClass();
if (attachmentClass == SignalOnlyAttachment.class) {
signalOnlyAttachment = (SignalOnlyAttachment) attachment;
} else if (attachmentClass == SignalAttachment.class) {
signalAttachment = (SignalAttachment) attachment;
}
}
public Object attachment() {
if (signalAttachment != null) {
return signalAttachment;
}
if (signalOnlyAttachment != null) {
return signalOnlyAttachment;
}
return null;
}
public long getSid() {
return sid;
}
@@ -1,63 +0,0 @@
/*
* Copyright (C) 2020 The zfoo Authors
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.net.router.attachment;
import com.zfoo.protocol.anno.Protocol;
/**
* 主要用来支持godot,unity,ts这种异步语法的使用,做为async/await语法的支撑
*
* @author godotg
* @version 3.0
*/
@Protocol(id = 1)
public class SignalOnlyAttachment {
private int signalId;
private long timestamp;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SignalOnlyAttachment that = (SignalOnlyAttachment) o;
return signalId == that.signalId;
}
@Override
public int hashCode() {
return signalId;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public int getSignalId() {
return signalId;
}
public void setSignalId(int signalId) {
this.signalId = signalId;
}
}
-1
View File
@@ -5,7 +5,6 @@
<module id="1" name="native">
<protocol location="com.zfoo.net.router.attachment.SignalAttachment"/>
<protocol location="com.zfoo.net.router.attachment.SignalOnlyAttachment"/>
<protocol location="com.zfoo.net.router.attachment.GatewayAttachment"/>
<protocol location="com.zfoo.net.router.attachment.UdpAttachment"/>
<protocol location="com.zfoo.net.router.attachment.HttpAttachment"/>
+1
View File
@@ -72,6 +72,7 @@
</exclusions>
</dependency>
<!-- 需要保持和spring-boot-starter-json里的jackson同样的版本-->
<!-- jsonbytecode generation to replace use of Reflection for field access and method calls(Jackson涡轮增压,字节码增强解析json) -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>