All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feingto.iot.server.handler.WebSocketMessageHandler Maven / Gradle / Ivy

There is a newer version: 1.2.5.RELEASE
Show newest version
package com.feingto.iot.server.handler;

import com.feingto.iot.common.handler.DefaultChannelInboundHandler;
import com.feingto.iot.server.serialize.JSON;
import com.feingto.iot.common.model.custom.ChartMessage;
import com.feingto.iot.common.model.custom.MessageChannel;
import com.feingto.iot.server.cache.ChannelCache;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.ReferenceCountUtil;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * WebSocket 消息处理器
 *
 * @author longfei
 */
@Slf4j
@Sharable
public class WebSocketMessageHandler extends DefaultChannelInboundHandler {
    @Setter
    private String wsUri = "/websocket";
    private WebSocketServerHandshaker handshake;

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ChannelCache.getInstance().remove(ctx.channel().id().asLongText());
        super.channelInactive(ctx);
    }

    @Override
    public void handleMessage(ChannelHandlerContext ctx, Object msg) {
        boolean release = true;
        try {
            if (msg instanceof WebSocketFrame) {
                this.handleWebSocketFrame(ctx, (WebSocketFrame) msg);
            } else if (msg instanceof FullHttpRequest) {
                FullHttpRequest request = (FullHttpRequest) msg;
                if (request.decoderResult().isSuccess() && wsUri.equals(request.uri())
                        && "websocket".equals(request.headers().get("Upgrade"))) {
                    this.webSocketHandshake(ctx, request);
                } else {
                    release = false;
                    ctx.fireChannelRead(request);
                }
            }
        } finally {
            if (release) {
                ReferenceCountUtil.release(msg);
            }
        }
    }

    /**
     * WebSocket握手
     */
    private void webSocketHandshake(ChannelHandlerContext ctx, FullHttpRequest request) {
        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                WebSocketScheme.WS + "://" + request.headers().get(HttpHeaderNames.HOST),
                null, false);
        handshake = wsFactory.newHandshaker(request);
        if (handshake == null) {
            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
        } else {
            handshake.handshake(ctx.channel(), request);
        }
    }

    /**
     * 处理WebSocket请求响应
     */
    private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        if (frame instanceof CloseWebSocketFrame) {
            handshake.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
            return;
        }

        if (frame instanceof PingWebSocketFrame) {
            ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
            return;
        }

        if ((frame instanceof TextWebSocketFrame)) {
            String text = ((TextWebSocketFrame) frame).text();
            log.debug("Received websocket message: " + text);
            ChartMessage message = JSON.getInstance().json2pojo(text, ChartMessage.class);
            // 缓存
            ChannelCache.getInstance().put(ctx.channel().id().asLongText(), new MessageChannel()
                    .channel(ctx.channel())
                    .username(message.from()));
            // 发送聊天消息
            ChannelCache.getInstance().push(message);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy