@Override public void channelInactive(ChannelHandlerContext ctx) { var hardwareChannel = ctx.channel(); var state = getHardState(hardwareChannel); if (state != null) { var session = sessionDao.get(state.userKey); if (session != null) { var device = state.device; log.trace("Hardware channel disconnect for {}, dashId {}, deviceId {}, token {}.", state.userKey, state.dash.id, device.id, device.token); sentOfflineMessage(ctx, session, state.dash, device); } } }
public MQTTHardwareServer(Holder holder) { super(holder.props.getProperty("listen.address"), holder.props.getIntProperty("hardware.mqtt.port"), holder.transportTypeHolder); var hardTimeoutSecs = holder.limits.hardwareIdleTimeout; var mqttHardwareLoginHandler = new MqttHardwareLoginHandler(holder); var alreadyLoggedHandler = new AlreadyLoggedHandler(); var hardwareChannelStateHandler = new HardwareChannelStateHandler(holder); channelInitializer = new ChannelInitializer<>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline() .addLast("MqttIdleStateHandler", new IdleStateHandler(hardTimeoutSecs, hardTimeoutSecs, 0)) .addLast(hardwareChannelStateHandler) .addLast(new MqttDecoder()) .addLast(MqttEncoder.INSTANCE) .addLast(mqttHardwareLoginHandler) .addLast(alreadyLoggedHandler); } }; log.debug("hard.socket.idle.timeout = {}", hardTimeoutSecs); }
private void sendPushNotification(ChannelHandlerContext ctx, Notification notification, int dashId, Device device) { var deviceName = ((device == null || device.name == null) ? "device" : device.name); var message = pushNotificationBody.replace(Placeholders.DEVICE_NAME, deviceName); if (notification.notifyWhenOfflineIgnorePeriod == 0 || device == null) { notification.push(gcmWrapper, message, dashId ); } else { //delayed notification //https://github.com/blynkkk/blynk-server/issues/493 ctx.executor().schedule(new DelayedPush(device, notification, message, dashId), notification.notifyWhenOfflineIgnorePeriod, TimeUnit.MILLISECONDS); } }
@Override protected void channelRead0(ChannelHandlerContext ctx, MqttConnectMessage message) { String username = message.payload().userName().trim().toLowerCase(); String token = new String(message.payload().passwordInBytes(), CharsetUtil.UTF_8); TokenValue tokenValue = holder.tokenManager.getTokenValueByToken(token); if (tokenValue == null || !tokenValue.user.email.equalsIgnoreCase(username)) { log.debug("MqttHardwareLogic token is invalid. Token '{}', '{}'", token, ctx.channel().remoteAddress()); ctx.writeAndFlush(createConnAckMessage(CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD), ctx.voidPromise()); return; } User user = tokenValue.user; Device device = tokenValue.device; DashBoard dash = tokenValue.dash; ChannelPipeline pipeline = ctx.pipeline(); HardwareStateHolder hardwareStateHolder = new HardwareStateHolder(user, tokenValue.dash, device); pipeline.replace(this, "HHArdwareMqttHandler", new MqttHardwareHandler(holder, hardwareStateHolder)); Session session = holder.sessionDao.getOrCreateSessionByUser( hardwareStateHolder.userKey, ctx.channel().eventLoop()); if (session.isSameEventLoop(ctx)) { completeLogin(ctx.channel(), session, user, dash, device, -1); } else { log.debug("Re registering hard channel. {}", ctx.channel()); ReregisterChannelUtil.reRegisterChannel(ctx, session, channelFuture -> completeLogin(channelFuture.channel(), session, user, dash, device, -1)); } }
HardwareLoginHandler hardwareLoginHandler = new HardwareLoginHandler(holder, port); HardwareChannelStateHandler hardwareChannelStateHandler = new HardwareChannelStateHandler(holder); AlreadyLoggedHandler alreadyLoggedHandler = new AlreadyLoggedHandler(); int maxWebLength = holder.limits.webRequestMaxSize;
private void createSessionAndReregister(ChannelHandlerContext ctx, User user, DashBoard dash, Device device, int msgId) { HardwareStateHolder hardwareStateHolder = new HardwareStateHolder(user, dash, device); ChannelPipeline pipeline = ctx.pipeline(); pipeline.replace(this, "HHArdwareHandler", new HardwareHandler(holder, hardwareStateHolder)); Session session = holder.sessionDao.getOrCreateSessionByUser( hardwareStateHolder.userKey, ctx.channel().eventLoop()); if (session.isSameEventLoop(ctx)) { completeLogin(ctx.channel(), session, user, dash, device, msgId); } else { log.debug("Re registering hard channel. {}", ctx.channel()); ReregisterChannelUtil.reRegisterChannel(ctx, session, channelFuture -> completeLogin(channelFuture.channel(), session, user, dash, device, msgId)); } }
private void sentOfflineMessage(ChannelHandlerContext ctx, Session session, DashBoard dashBoard, Device device) { //this is special case. //in case hardware quickly reconnects we do not mark it as disconnected //as it is already online after quick disconnect. //https://github.com/blynkkk/blynk-server/issues/403 boolean isHardwareConnected = session.isHardwareConnected(dashBoard.id, device.id); if (!isHardwareConnected) { log.trace("Changing device status. DeviceId {}, dashId {}", device.id, dashBoard.id); device.disconnected(); } if (!dashBoard.isActive) { return; } Notification notification = dashBoard.getNotificationWidget(); if (notification != null && notification.notifyWhenOffline) { sendPushNotification(ctx, notification, dashBoard.id, device); } else if (!dashBoard.isNotificationsOff) { session.sendOfflineMessageToApps(dashBoard.id, device.id); } }
var appIdleTimeout = holder.limits.appIdleTimeout; var hardwareChannelStateHandler = new HardwareChannelStateHandler(holder); var hardwareLoginHandler = new HardwareLoginHandler(holder, port);