spring boot ip地址解析

从请求头中获取ip地址

http还没升级的时候可以从请求头中获取ip地址
注意如果是Nginx的话直接获取会获取到Nginx的地址
保存到neetty附件

 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest httpRequest = (HttpRequest) msg;
            UrlBuilder urlBuilder = UrlBuilder.ofHttp(httpRequest.getUri());
            Optional<String> optional = Optional.of(urlBuilder)
                    .map(UrlBuilder::getQuery)
                    .map(k -> k.get("token"))
                    .map(CharSequence::toString);
            //如果token存在
            optional.ifPresent(s -> NettyUtil.setAttr(ctx.channel(), NettyUtil.TOKEN, s));
            //移除后面的所有参数
            httpRequest.setUri(urlBuilder.getPath().toString());
            //获取用户ip 如果是从Nginx走的话
            String ip = httpRequest.headers().get("X-Real-Ip");
            //本地ip
            if (Strings.isBlank(ip)) {
                InetSocketAddress inetSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
                ip = inetSocketAddress.getAddress().getHostAddress();
            }
            log.info("ws升级前ip地址:{}",ip);
            //保存到channel附件
            NettyUtil.setAttr(ctx.channel(), NettyUtil.IP, ip);
            //处理器只需要用一次
            ctx.pipeline().remove(this);
        }
        ctx.fireChannelRead(msg);
    }

用户带着token连接ws

 //用户带着token过来
        } else if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
            webSocketService.connect(ctx.channel());
            String token = NettyUtil.getAttr(ctx.channel(), NettyUtil.TOKEN);
            if (StrUtil.isNotBlank(token)) {
                webSocketService.authorize(ctx.channel(), token);
            }
        }

解析ip

发送了一个事件 异步进行处理

/**
     * 用户上线发送消息
     * @param channel
     * @param user
     * @param token
     */
    private void loginSuccess(Channel channel, User user, String token) {
        //保存channel uid
        WSChannelExtraDTO wsChannelExtraDTO = ONLINE_WS_MAP.get(channel);
        wsChannelExtraDTO.setUuid(user.getId());
        //推送成功消息
        sandMsg(channel, WebSocketAdapter.buildResp(user, token));
        //用户上线成功事件
        user.setLastOptTime(new Date());
        IpInfo ipInfo = new IpInfo();
        ipInfo.setCreateIp(NettyUtil.getAttr(channel,NettyUtil.IP));
        ipInfo.setUpdateIp(NettyUtil.getAttr(channel,NettyUtil.IP));
        user.refreshIp(NettyUtil.getAttr(channel,NettyUtil.IP));
        applicationEventPublisher.publishEvent(new UserOnlineEvent(this,user));
    }

订阅事件

先设置在线状态
后续进行ip解析

   @EventListener(classes = UserOnlineEvent.class)
    @Async
    public void sandUserIp(UserOnlineEvent event) {
        User user = BeanCopyUtils.copyBean(event.getUser(), User.class);
        user.setActiveStatus(UserActiceStatusEnum.ONLINE.getType());
        userDao.updateById(user);
        //用户ip解析
        ipService.refreshIpDetailAsync(user.getId());
    }

ip解析

这里进行三次解析ip每次都等待两秒

private static IpDetail tryGetIPDetailOrNullTreeTimes(String ip) {
        for (int i = 0; i < 3; i++) {
            IpDetail ipDetail = GetIPDetailOrNull(ip);
            if (Objects.nonNull(ipDetail)) {
                return ipDetail;
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                log.error("tryGetIPDetailOrNullTreeTimes InterruptedException:",e);
            }
        }
        return null;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值