Skip to content

鸿蒙系统微信小游戏无法连接websocket,安卓正常 #54

Description

@VkingLangzi

服务器接收Socket代码

`import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import org.springframework.stereotype.Component;

/**

  • TLS版本检测器

  • 通过分析SSL握手包来准确获取客户端使用的TLS版本
    */
    @component
    public class TlsVersionDetector extends ChannelInboundHandlerAdapter {

    @OverRide
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    if (msg instanceof ByteBuf) {
    ByteBuf buf = (ByteBuf) msg;
    String clientIp = ctx.channel().remoteAddress().toString();

         // 尝试解析TLS握手包
         String tlsVersion = parseTlsVersion(buf);
         if (tlsVersion != null) {
             // 根据TLS版本决定日志级别
             if (isSecureTlsVersion(tlsVersion)) {
                 LogP.info("检测到客户端 {} 使用TLS版本: {}", clientIp, tlsVersion);
             } else {
                 LogP.warn("检测到客户端 {} 使用不安全的TLS版本: {} (建议升级到TLS1.2或TLS1.3)", clientIp, tlsVersion);
             }
             // 解析完成后移除自己,避免影响后续处理
             ctx.pipeline().remove(this);
         } else {
             LogP.info("无法检测到客户端 {} 使用TLS版本: {}", clientIp, tlsVersion);
         }
     }
    
     // 继续传递消息
     super.channelRead(ctx, msg);
    

    }

    /**

    • 判断是否为安全的TLS版本
      */
      private boolean isSecureTlsVersion(String tlsVersion) {
      return "TLSv1.2".equals(tlsVersion) || "TLSv1.3".equals(tlsVersion);
      }

    /**

    • 解析TLS握手包中的版本信息
      */
      private String parseTlsVersion(ByteBuf buf) {
      if (buf.readableBytes() < 5) {
      return null;
      }

      // 保存当前读取位置
      int readerIndex = buf.readerIndex();

      try {
      // TLS记录格式:
      // Byte 0: Content Type (0x16 = Handshake)
      // Byte 1-2: Protocol Version
      // Byte 3-4: Length

       byte contentType = buf.readByte();
       if (contentType != 0x16) { // 不是握手包
           return null;
       }
      
       // 读取协议版本 (2 bytes)
       byte majorVersion = buf.readByte();
       byte minorVersion = buf.readByte();
       return decodeTlsVersion(majorVersion, minorVersion);
      

      } catch (Exception e) {
      LogP.debug("解析TLS版本时出错: {}", e.getMessage());
      return null;
      } finally {
      // 恢复读取位置
      buf.readerIndex(readerIndex);
      }
      }
      /**

    • 将版本字节转换为TLS版本字符串
      */
      private String decodeTlsVersion(byte major, byte minor) {
      if (major == 3) {
      switch (minor) {
      case 0:
      return "SSLv3.0";
      case 1:
      return "TLSv1.0";
      case 2:
      return "TLSv1.1";
      case 3:
      return "TLSv1.2";
      case 4:
      return "TLSv1.3";
      default:
      return "TLS未知版本(3." + (minor & 0xFF) + ")";
      }
      } else if (major == 2) {
      return "SSLv2.0";
      } else {
      return "未知协议版本(" + (major & 0xFF) + "." + (minor & 0xFF) + ")";
      }
      }

    @OverRide
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    // 如果出现异常,移除自己并继续
    ctx.pipeline().remove(this);
    super.exceptionCaught(ctx, cause);
    }
    }`

报错日志

2025-09-13T15:56:38.681+0800 [soccer3 PVP server_NETTY_WORKER_1] ERROR n.g.l.netty.MessageDataServerHandleio.netty.handler.ssl.ReferenceCountedOpenSslEngine$OpenSslHandshakeException: error:10000416:SSL routines:OPENSSL_internal:SSLV3_ALERT_CERTIFICATE_UNKNOWN
io.netty.handler.codec.DecoderException: io.netty.handler.ssl.ReferenceCountedOpenSslEngine$OpenSslHandshakeException: error:10000416:SSL routines:OPENSSL_internal:SSLV3_ALERT_CERTIFICATE_UNKNOWN
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:499)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:61)
at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:425)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:66)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.lang.Thread.run(Thread.java:748)
Caused by: io.netty.handler.ssl.ReferenceCountedOpenSslEngine$OpenSslHandshakeException: error:10000416:SSL routines:OPENSSL_internal:SSLV3_ALERT_CERTIFICATE_UNKNOWN
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.newSSLExceptionForError(ReferenceCountedOpenSslEngine.java:1377)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.shutdownWithError(ReferenceCountedOpenSslEngine.java:1089)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.sslReadErrorResult(ReferenceCountedOpenSslEngine.java:1399)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1325)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1426)
at io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1469)
at io.netty.handler.ssl.SslHandler$SslEngineType$1.unwrap(SslHandler.java:223)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1353)
at io.netty.handler.ssl.SslHandler.decodeNonJdkCompatible(SslHandler.java:1257)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1297)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions