缺少升级:在 netty 4.x 上同时提供 http 和 ws

2024-06-24

我正在 netty 上编写一个聊天应用程序。

我尝试为两者服务HTTP and WS,但是http响应只是这些消息

不是 WebSocket 握手请求:缺少升级

这是我的代码片段。

在InitChannel方法中

p.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast( new LoggingHandler(LogLevel.INFO))
.addLast(new WebSocketServerProtocolHandler("/chat"),
        new WsUserAcceptHandler(), new WsChatServerHandler())
.addLast(new HttpStaticFileHandler("/", ChatServer.index))
.addLast(new HttpNotFoundHandler());

而在channelRead上,WsUserAcceptHandler、WsChatHandler都只处理TextWebSocketFrame,其他的都是ctx.fireChannelRead(msg)

WsUserAcceptHandler

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        System.out.println("WsUserAcceptHandler#channelRead :" + msg.getClass());
        if (msg instanceof TextWebSocketFrame) {
            TextWebSocketFrame tMsg = (TextWebSocketFrame) msg;
            ChatMessage chatMsg = ChatMessage.parse(tMsg.text());

            if (chatMsg.getCommand().equals("CONN")) {


                SqlSession sqlSession = SqlSessionFactoryManager
                        .getSqlSession();
                User u = new User();
                ChatRoom roomInfo = new ChatRoom();

                try {
                    u.setUserSessionkey(chatMsg.getSessionKey());
                    UserMapper userMapper = sqlSession
                            .getMapper(UserMapper.class);
                    u = userMapper.get(u);

                    ChatInfoMapper chatInfoMapper = sqlSession
                            .getMapper(ChatInfoMapper.class);
                    roomInfo = chatInfoMapper.getRoomInfo(chatMsg.getRoomNo());

                } catch (Exception e) {

                } finally {
                    sqlSession.close();
                }

                if (u != null) {
                    System.out.println("userInfo");
                    System.out.println(u.toString());

                    AttrKeys attrs = AttrKeys.getInstance();

                    ctx.channel().attr(attrs.sessionKey())
                            .set(u.getUserSessionkey());
                    ctx.channel().attr(attrs.userInfo()).set(u);
                    currClients.registerUserChannelGroup(
                            String.valueOf(chatMsg.getRoomNo()), ctx.channel());

                    ChatDataMapper cdm = new ChatDataMapper();
                    List<ChatMessage> latests = cdm.gets(chatMsg.getRoomNo(), 20);

                    HashMap<String, Object> map = new HashMap<String, Object>();
                    map.put("recentMessages", latests);
                    map.put("roomInfo", roomInfo);

                    JsonResultSet<HashMap<String, Object>> res = new JsonResultSet<HashMap<String, Object>>();
                    res.setResultCode("S0000");
                    res.setResultMessage("Success");
                    res.setCommand(chatMsg.getCommand());
                    res.setResult(map);
                    System.out.println(res.toJsonString());

                    TextWebSocketFrame outputMsg = new TextWebSocketFrame(
                            res.toJsonString());
                    ctx.writeAndFlush(outputMsg);
                } else {
                    ctx.flush();
                }

                // ctx.writeAndFlush(outputMsg);
            } else if (chatMsg.getCommand().equals("DISCONN")) {
                ctx.channel().attr(sessionKeyAttr).get();
                currClients.unregisterUserChannelGroup(
                        String.valueOf(chatMsg.getRoomNo()), ctx.channel());

                ctx.fireChannelInactive();
            }
        }

        ctx.fireChannelRead(msg); // if not instance of TextWebsocketFrame
    }

WsChatServerHandler

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        System.out.println("WsChatServerHandler##channelRead :" + msg.getClass());
        if(msg instanceof TextWebSocketFrame){
            ChatMessage chatMsg = ChatMessage.parse(((TextWebSocketFrame) msg).text());
//          chatMsg.setC_user_nm(ctx.channel().attr(sessionKeyAttr).get()  );
            if(chatMsg.getCommand().equals("TEXT")){
                ChannelGroup roomUsers = currClients.getUserChannelGroup(String.valueOf(chatMsg.getRoomNo ()));

                AttrKeys attrs = AttrKeys.getInstance();
                User u = ctx.channel().attr(attrs.userInfo()).get();


                JsonResultSet<ChatMessage> res = new JsonResultSet<ChatMessage>();
                res.setResultCode("S0000");
                res.setResultMessage("Success");
                res.setCommand(chatMsg.getCommand());

                chatMsg.setSessionKey(null);
                chatMsg.setCommand(null);

                chatMsg.setSeq(ChatServer.nextChatDataSeq());
                chatMsg.setUserSeq(u.getUserSeq());
                chatMsg.setUserNm(u.getUserNm());
                chatMsg.setUserType(u.getUserType());
                chatMsg.setUserThumb(StaticVar.default_img_url+u.getUserThumb()+"&imgMode=origin");
                chatMsg.setUserPic(StaticVar.default_img_url+u.getUserPic()+"&imgMode=thumb");

                ChatDataMapper mapper = new ChatDataMapper();
                mapper.put(chatMsg);

                System.out.println(chatMsg.toString());

                res.setResult(chatMsg);

                TextWebSocketFrame outputMsg = new TextWebSocketFrame(res.toJsonString());

                sendPush(chatMsg, String.valueOf(chatMsg.getRoomNo()));
//              gcmTest(chatMsg);

                roomUsers.writeAndFlush(outputMsg);
            } else if(chatMsg.getCommand().equals("MORE")){

            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }

我解决了。是Netty版本问题。

我在Netty 4.1.0.CR6之前使用过,然后我尝试更改之后的版本和4.0.0,然后我的问题就消失了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

缺少升级:在 netty 4.x 上同时提供 http 和 ws 的相关文章

  • 在处理程序之后访问 HTTP 请求上下文

    在我的日志记录中间件 链中的第一个 中 我需要访问一些在链下游的某些身份验证中间件中编写的上下文 并且仅在处理程序本身执行之后 旁注 需要首先调用日志记录中间件 因为我需要记录请求的持续时间 包括在中间件中花费的时间 此外 当权限不足时 身
  • 是否可以修改 $_SESSION 变量?

    恶意用户是否可以将 SESSION 在 php 中 变量设置为他想要的任何值 很大程度上取决于您的代码 有一点非常明显 SESSION username REQUEST username
  • 返回重定向作为对 Ajax(fetch、XHR 等)请求的响应

    如果浏览器收到对 ajax 请求的重定向响应 会发生什么 如果浏览器收到对 ajax 请求的重定向响应 会发生什么 如果服务器发送重定向 又名 302 响应加上 Location 标头 浏览器将自动遵循重定向 对此的回应second请求 假
  • 浏览器显示 clojure 环中不存在 access-control-allow-origin 标头

    我通过客户端浏览器向服务器发出请求 如下所示https example com bar https example com bar 但出现错误 Access to XMLHttpRequest at https example com ba
  • 使用 Anypoint Studio (MULE) 在本地主机上找不到资源

    我尝试按照 MuleSoft 网站上建议的教程进行操作 我首先从这个例子开始
  • 过滤条件的查询字符串与资源路径

    背景 我有2个资源 courses and professors A course具有以下属性 ID topic 学期号 年 部分 教授 id A professor具有以下属性 ID 学院 超级用户 名 姓 所以 你可以说一门课程有一位教
  • 从 R 中的 HTTPS 连接逐行读取

    当创建连接时open r 它允许逐行读取 这对于批量处理大数据流非常有用 例如这个脚本 https gist github com jeroenooms d33a24958d99bb969ac0通过一次读取 100 行来解析相当大的 gzi
  • 动态img(或视频)标签根本不加载资源,HTTP请求处于“待处理”状态

    我尝试使用以下方法在 Web 应用程序上加载资源时遇到一些问题img or videoHTML 标签 我在我的应用程序中使用 Angular 并动态设置src的参数img标签 使用ng src src 指示 没有那么多图像和资源需要加载 在
  • HTTP 状态码 302

    我正在用 Ruby 开发 Rails 后端 并且想将数据发布到该服务器 但如果我用 PAW 发出后请求 我就会被重定向 我是 Http 请求的新手 有人可以向我解释一下功能以及如何使用 http post 请求吗 我想在我的服务器数据库 s
  • php 注意到 $GLOBALS['HTTP_SERVER_VARS']['HTTP_HOST'] 中未定义索引 http_host

    突然 在最近的 php 版本更新后 我从 php 收到了此通知 它在多个地方使用 特别是我的 htmlMimeMail 类 代码是 mail gt setSMTPParams mail xxxx xxx 26 GLOBALS HTTP SE
  • 如何修复错误“AttributeError:‘模块’对象在 python3 中没有属性‘客户端’?

    以下是我的代码 import http h1 http client HTTPConnection www bing com 我认为没问题 但是 python 给了我以下错误 AttributeError 模块 对象没有属性 客户端 我想知
  • 无法使用 Net::HTTP 在我的 ruby​​ 代码中发出 HTTP 删除请求

    我在 ruby 代码中使用 Net HTTP 来发出 http 请求 例如 我要发出一个帖子请求 require net http Net HTTP post form url email gt email password gt pass
  • OAuth2 - 无需用户交互即可授权

    因此 我尝试通过外部应用程序的 API 访问我自己的数据 我只需要访问我自己的数据 不尝试从我的任何用户帐户接收数据 因此他们不需要授权任何内容 显然我需要避免任何重定向 随着我对 OAuth 的研究越多 这似乎是标准流程 该过程被击中 a
  • 当远程(Http)文件更改时如何执行操作?

    我想创建一个脚本 用于检查 URL 并在远程文件的 Last Modified 标头更改时执行操作 下载 解压缩 我考虑过使用curl 获取标头 但随后我必须将其存储在每个文件的某个位置并执行日期比较 有没有人对使用 大部分 标准 UNIX
  • Cordova:如何诊断 ajax 不适用于 UWP(Windows 商店)应用程序

    我有一个简单的 Cordova 应用程序 在构建并作为 Windows UWP 应用程序运行时 ajax 调用会以某种方式阻止我的工作网络 我以前曾多次问过这个问题 但我想尝试改写 因为从未得到任何解决方案 应用程序 ajax 调用在我的家
  • 检查发送到网页的请求数

    我正在编写一个 Java 多线程应用程序 它可以访问不同 Web 服务器的数百万个 有时甚至数十亿个 URL 这个想法是检查这些 URL 是否给出有效的 200OK 响应或 404 其他代码 我如何知道我的程序是否不会在他们的服务器上造成高
  • 将参数传递给 http.HandlerFunc

    我正在使用 Go 的内置 http 服务器pat http github com bmizerany pat响应某些 URL mux Get products http HandlerFunc index func index w http
  • 如何远程调试Lua?

    我正在寻找远程调试 Lua 的最佳方法 例如从网络浏览器 I saw RemDebug http www keplerproject org remdebug 但最后一次项目更新是在 2006 年完成的 它适用于 Lua 5 0 和 5 1
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • 通过标记或JS强制下载

    假设我在 CDN 来自 Rackspace 的云文件 上有一个文件 以及一个包含该文件链接的静态 html 页面 有什么方法可以强制下载此文件 以防止它在浏览器中打开 例如 mp3 我们可以让我们的服务器读取该文件并将相应的标头设置为 he

随机推荐

  • C++ 析构函数中的异常

    从其他线程 我知道我们不应该在析构函数中抛出异常 但对于下面的例子来说 它确实有效 这是否意味着我们只能在一个实例的析构函数中抛出异常 我们应该如何理解这个代码示例 include
  • 内置数组的大小是什么类型?

    当推导非类型模板参数时 比如说n 的类型n参数和参数之间必须完全匹配 因此以下代码将无法编译 至少在 GCC 和 clang 上 include
  • 错误代码 CS1061 运算符“*”不能应用于“Vector 3”和“Vector3”类型的操作数。我该如何解决这个问题

    您好 我正在尝试使用我的脚本根据速度为角色创建统一的运动 但出现错误CS0019 操作员 不能应用于 Vector3 和 Vector3 类型的操作数 不断出现 我尝试过类似问题的解决方案错误 CS0019 运算符 无法应用于类型 Vect
  • 防止在 AJAX 请求上发送 Cookie

    我有一个从脚本调用的 Web 服务 但不需要存储在 cookie 中的任何信息 每当我向服务发出请求时 cookie 都会随之发送 我知道默认情况下 cookie 是通过 HTTP 请求发送的 但是有什么方法可以覆盖该行为而不发送 cook
  • 什么是 jsconfig.json?

    如果我在 Internet 上搜索相同的问题 那么我只会得到 Visual Studio Code 网站和一些实现它的博客的链接 我想知道那是jsconfig json特定于 Visual Studio Code 或javascript w
  • IdentityServer 4 的自定义登录 UI

    我正在做一个类似于 IdentityServer4 Quickstart UI 的项目 但将登录 UI 和 IdentityServer 分开 更具体地说 IdentityServer 本身将是一个纯 WebApi 登录 UI 可以是使用
  • jQuery Ajax 调用在 IE 中非常慢,但在 Firefox 中却很快

    我正在执行 jQuery ajax 返回一个调用List
  • 模态 Segue,导航栏消失

    我正在使用 Xcode 4 6 1 在 Objective C 上进行编码 我想知道当我在两个视图控制器之间创建模态转场时如何保持导航栏显示 因为我正在故事板中进行转场 并且当我运行应用程序时 第二个视图控制器的导航栏消失 并且我在该栏上有
  • 运行“bundle install”失败并要求我运行“bundle install”

    事实上 当从我从 git 存储库克隆的现有 Rails 应用程序内部运行时 所有与 gem 相关的命令都会导致相同的错误消息 bundle install Could not find tzinfo 0 3 27 in any of the
  • 多处理器提升::线程?所有线程都在一个处理器上运行

    我有一个令人尴尬的并行问题 我想在多个处理器上执行 我原以为boost thread会自动将新线程发送到新处理器 但所有线程都在与父进程相同的核心上执行 是否可以让每个线程在不同的处理器上运行 或者我是否需要 MPI 之类的东西 我的怀疑是
  • 如何恢复已删除的文件[重复]

    这个问题在这里已经有答案了 可能的重复 在 Git 存储库中恢复已删除的文件 https stackoverflow com questions 953481 restore a deleted file in a git repo 如何恢
  • 绑定到 Android 中的 AccessibilityService?

    我创建了一个安卓Service 它扩展了AccessibilityService 从我的Activity 我想绑定到那个Service 因为我需要发送信息Service to Activity 我需要示例代码 我已经搜索过谷歌 但没有找到类
  • 从元组类型中删除所有可选项目

    假设我想用可选项目来转换一个元组 例如 1 2 3 4 到仅包含所需项目的数组 gt 1 2 我想出的如下所示 它永远不会转向所有可选项目 而我被困在这里 type OnlyReq
  • 如何为 Yarn 设置自定义缓存路径?

    我刚刚安装了 Yarn 并尝试从 npm 切换 我尝试像这样设置缓存路径 但没有成功 yarn cache folder usr local Caches yarn yarn global cache folder usr local Ca
  • 如何使用Google Chrome缩略图预览服务?

    有人知道如何使用 google chrome 服务来生成网站缩略图 新标签上浏览次数最多的网站 有想法做类似的事情吗 These 浏览 chrome 源代码我找不到任何有趣的东西 你呢 来源在这里 http src chromium org
  • 拓扑排序卡恩算法 BFS 或 DFS

    拓扑排序的方法是BFS还是DFS 哪个正确 我认为BFS是对的 但有些网站说DFS 有些网站说BFS 我很困惑 卡恩算法与 BFS 或 DFS 相同吗 或者BFS 或DFS 只是卡恩算法的工具 Kahn算法和DFS在实践中都用于拓扑排序 选
  • MFC中如何获取子菜单?

    我正在尝试获取一个子菜单 以便我可以在显示它之前对其进行更改 所以我创建了一个OnInitMenu 我的窗口的处理程序 我本来计划使用pMenu gt GetMenuItemInfo 获取子菜单 然而 这似乎行不通 为了找到我想要的菜单 我
  • React fetch 有错误 fetch 被 CORS 策略阻止 [重复]

    这个问题在这里已经有答案了 我尝试点击登录按钮调用获取 REST 调用 但是 问题是提取失败 并在 Javascript 控制台中显示此错误消息 从源获取的访问已被 CORS 策略阻止 请求的资源上不存在 Access Control Al
  • 回调已经被称为 Angular cli

    我更新了我的 Angular CLI 然后我在 ng 服务中遇到错误 Callback was already called at throwError node modules neo async async js 14 11 at no
  • 缺少升级:在 netty 4.x 上同时提供 http 和 ws

    我正在 netty 上编写一个聊天应用程序 我尝试为两者服务HTTP and WS 但是http响应只是这些消息 不是 WebSocket 握手请求 缺少升级 这是我的代码片段 在InitChannel方法中 p addLast new H