xin.alum.aim.handler.AimReceiver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aim-starter Show documentation
Show all versions of aim-starter Show documentation
aim-starter 基于netty的WebSocket和Socket通信包
package xin.alum.aim.handler;
import com.google.protobuf.InvalidProtocolBufferException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroupFuture;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import xin.alum.aim.AIM;
import xin.alum.aim.constant.ChannelAttr;
import xin.alum.aim.constant.ChannelClose;
import xin.alum.aim.constant.ChannelPlatform;
import xin.alum.aim.groups.Session;
import xin.alum.aim.groups.SessionGroups;
import xin.alum.aim.groups.Sessions;
import xin.alum.aim.model.Reply;
import xin.alum.aim.model.Sent;
import xin.alum.aim.model.proto.Packet;
import xin.alum.aim.model.proto.ProtoJsonUtil;
import xin.alum.aim.util.GZipUtil;
import java.io.InputStream;
/**
* 此类为源码测试接受者
* 正式业务请重写此服务类
*
* @auther alum(alum @ live.cn)
* @date 2021/8/5 10:01
*/
public class AimReceiver implements AimReceive {
/**
* 所有会话
*/
@Autowired
protected Sessions sessions;
/**
* 所有群组
*/
@Autowired
protected SessionGroups groups;
/**
* 日志对象
*/
protected final InternalLogger logger = InternalLoggerFactory.getInstance(this.getClass());
/**
* WebSocket握手处理逻辑,绑定用户信息到会话系统
*
* @param ch 当前连接通道
* @param req 当前上行请求,URL参数已经放入ch中
* @param res 握手失败 return false 输出给客户端的对象
* @return
*/
@Override
public boolean onHandShake(Channel ch, FullHttpRequest req, FullHttpResponse res) {
return true;
}
/**
* Socks基于自定义Bing握手处理逻辑,绑定用户信息到会话系统
*
* @param ch 通道
* @param in 握手数据包
* @return
*/
@Override
public boolean onHandShake(Channel ch, ByteBuf in) {
return true;
}
/**
* Socks基于ProtoBuf-Login的握手处理逻辑
*
* @param ch
* @param user
* @param token
* @return
*/
@Override
public boolean onHandShake(Channel ch, String user, String token) {
return true;
}
@Override
public void onHandShaked(Channel ch) {
if (sessions != null) {
sessions.bindUser(ch, ch.id().toString(), ChannelPlatform.NON, "");
}
}
@Override
public void onPing(Channel ch) {
}
/**
* Text类型数据处理,测试用,正式业务请重写
*
* @param ch
* @param text
*/
@Override
public void onText(Channel ch, String text) {
if (ch.attr(ChannelAttr.AGREEMENT).get() == Packet.Agreement.Text) {
ch.write(text);
} else {
text = GZipUtil.ungzip(AIM.properties.getGzip(), text);
ProtoJsonUtil protoJsonUtil = new ProtoJsonUtil(Packet.Data.getDescriptor());
Packet.Sent p = (Packet.Sent) protoJsonUtil.toProto(Packet.Sent.newBuilder(), text);
onRecive(ch, new Sent(p.getKey(), p.getData()));
}
}
/**
* 处理WebSocket binary请求
* 测试方法,正式业务请重写
*
* @param ch
* @param in
* @throws InvalidProtocolBufferException
*/
@Override
public void onByte(Channel ch, ByteBuf in) {
try {
if (ch.attr(ChannelAttr.AGREEMENT).get() == Packet.Agreement.Binary) {
logger.error("{}{}协议未实现", ch, Packet.Agreement.Binary);
return;
}
InputStream inputStream = new ByteBufInputStream(in);
Packet.Sent m = Packet.Sent.parseFrom(inputStream);
Sent t = new Sent(m.getKey(), m.getTimestamp(), m.getData());
onRecive(ch, t);
} catch (Exception e) {
logger.error("{} 数据解析异常,{},{}", ch.id(), e.getMessage(), e);
}
}
/**
* 测试方法,正式业务请重写
*
* @param ch
* @param s
*/
@Override
public void onRecive(Channel ch, Sent s) {
Reply reply = new Reply(s.getKey());
reply.setData(s.getData());
ChannelGroupFuture f = sessions.sends(s);
final int size = sessions.size();
f.addListener(t -> {
long time = System.currentTimeMillis() - reply.getTimestamp();
if (time > 5000 || f.isPartialFailure()) {
logger.warn("{}向【{}】群发【{}】人{},用时-{}", ch,sessions.name(), size, t.isSuccess(), time);
}
});
}
@Override
public Reply onKick(Channel ch, Session session) {
logger.warn("{}用户【{}】通过{}-{}登录", ch, session.getUid(), session.getPlatform(), session.getClientIp());
return new Reply("99", String.format("%s用户【%s】通过%s-%s登录", ch, session.getUid(), session.getPlatform(), session.getClientIp()));
}
@Override
public void onClose(Channel ch, ChannelClose close) {
logger.warn("{}UID-{},因{}而关闭.", ch,ch.attr(ChannelAttr.UID), close.name());
}
}