`
56553655
  • 浏览: 202897 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

The WebSocket protocol 76 - WebSocket 76 协议以及NETTY组装返回结果示例

阅读更多

    RFC文档地址:http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76

    原来的程序在GOOGLE的CHROME中使用WEBSOCKET通讯是没有问题,但有一次发现原来的程序在没有改动的情况下,在CHROME里面使用WEBSOCKET是,建立不了连接了,刚开始还以为是不小心改动了程序,后面经过仔细排查,终于发现是WEBSOCKET协议变了的原因,随着CHROME升级的时候一起就升级了。

    现在最新的WEBSOCKET协议为76号协议,它较原来的协议比较,增加了安全性方面的验证,要求服务在接到握手请求后,必须返回三个要素给客户端确认,两个信息分类来自Sec-WebSocket-Key1及Sec-WebSocket-Key2中的去除其它字符后的所有数字拼装串,除以其本身的空格后的各32位,第三部份是是后8个字节,再加MD5加密后,返回给客户端,然后客户端确认后,才算握手成功。

 

    以上提到的内容,参看协议文档中的“1.3.  Opening handshake

    以下是一个JAVA示例,通过NETTY根据请求,组装WEBSOCKET握手返回的源代码实现:

    private HttpResponse buildWebSocketRes(HttpRequest req) {
        HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
                                                   new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
        res.addHeader(HttpHeaders.Names.UPGRADE, HttpHeaders.Values.WEBSOCKET);
        res.addHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.UPGRADE);
        // Fill in the headers and contents depending on handshake method.
        if (req.containsHeader(Names.SEC_WEBSOCKET_KEY1) && req.containsHeader(Names.SEC_WEBSOCKET_KEY2)) {
            // New handshake method with a challenge:
            res.addHeader(Names.SEC_WEBSOCKET_ORIGIN, req.getHeader(Names.ORIGIN));
            res.addHeader(Names.SEC_WEBSOCKET_LOCATION, getWebSocketLocation(req));
            String protocol = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
            if (protocol != null) {
                res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
            }

            // Calculate the answer of the challenge.
            String key1 = req.getHeader(Names.SEC_WEBSOCKET_KEY1);
            String key2 = req.getHeader(Names.SEC_WEBSOCKET_KEY2);
            int a = (int) (Long.parseLong(filterNonNumeric(key1)) / filterNonSpace(key1).length());
            int b = (int) (Long.parseLong(filterNonNumeric(key2)) / filterNonSpace(key2).length());
            long c = req.getContent().readLong();
            ChannelBuffer input = ChannelBuffers.buffer(16);
            input.writeInt(a);
            input.writeInt(b);
            input.writeLong(c);
            ChannelBuffer output = null;
            try {
                output = ChannelBuffers.wrappedBuffer(MessageDigest.getInstance("MD5").digest(input.array()));
            } catch (NoSuchAlgorithmException e) {
                if (logger.isInfoEnabled()) {
                    logger.info("no such Algorithm : MD5. " + e);
                }
                e.printStackTrace();
            }

            res.setContent(output);
        } else {
            // Old handshake method with no challenge:
            res.addHeader(Names.WEBSOCKET_ORIGIN, req.getHeader(Names.ORIGIN));
            res.addHeader(Names.WEBSOCKET_LOCATION, getWebSocketLocation(req));
            String protocol = req.getHeader(Names.WEBSOCKET_PROTOCOL);
            if (protocol != null) {
                res.addHeader(Names.WEBSOCKET_PROTOCOL, protocol);
            }
        }

        return res;
    }

    

/**
     * 过滤掉非数字的字符<br>
     * 例如:str="uis sdj13 e8 kj*<ks90ao",则返回"13890"
     * 
     * @param str
     * @return 过滤后的字符串.如果str为空,则直接返回str
     */
    public static String filterNonNumeric(String str) {
        if (StringUtil.isEmpty(str)) {
            return str;
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);            
            if (NumberUtils.isNumber(String.valueOf(c))) {//NumberUtils是org.apache.commons.lang.math.NumberUtils
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * 过滤掉非空格的字符<br>
     * 例如:str="uis sdj13 e8 kj*<ks90ao",则返回"   "
     * 
     * @param str
     * @return 过滤后的字符串.如果str为空,则直接返回str
     */
    public static String filterNonSpace(String str) {
        if (StringUtil.isEmpty(str)) {
            return str;
        }

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (" ".equals(String.valueOf(c))) {
                sb.append(c);
            } else {
                sb.append("");
            }
        }

        return sb.toString();
    }

 

1
0
分享到:
评论

相关推荐

    spring-boot-protocol:springboot功能扩展-netty动态协议,可以支持各种网络协议的动态切换(单端口支持多个网络协议)。支持mmap,sendfile零拷贝,http请求批量聚合

    用Netty实现的Spring-boot-protocol将springboot的WebServer更改为NettyTcpServer,为用户扩展了网络编程的能力。多协议服务器,Springboot协议扩展包,允许单端口提供多协议服务。其中内置多个网络传输(标准与规范...

    Spring Boot 整合 Netty + WebSocket 实时消息推送

    2. **WebSocket Stomp协议**:在Spring Boot中,通常会使用STOMP(Simple Text Oriented Messaging Protocol)作为WebSocket的应用层协议。STOMP简化了消息的格式,使得客户端和服务器之间可以交换消息。Spring ...

    netty学习文件,实现http,websocket,protobuf

    Netty 是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。在本文中,我们将深入探讨Netty如何实现HTTP、WebSocket和Protobuf这三种通信方式,以及它们在服务器与客户端...

    netty-demos.zip

    WebSocket 示例是关于Websocket协议的实现,这是一个双向通信协议,常用于实时应用。这个示例会涵盖WebSocket握手过程,数据帧的发送与接收,以及错误处理。 通过这些示例,开发者可以学习到Netty的管道(Pipeline...

    使用Netty实现IMServer,支持Tcp和WebSocket实现。_Java_下载.zip

    在这个项目中,我们看到一个基于 Netty 实现的 IMServer,它同时支持 TCP 和 WebSocket 协议,这使得服务器能够处理即时通讯(IM)的需求,既可以通过传统的 TCP 连接进行可靠的数据传输,又可以利用 WebSocket 实现...

    c++ netty.zip

    【标题】:“C++ Netty.zip”涉及到的关键技术点包括Java的Netty服务器、TCP通信、C++套接字编程以及Google的Protocol Buffers(protobuf)在Java和C++之间的跨语言通信应用。 【描述】:这个压缩包文件提供了一个...

    Unity与Netty通信Demo

    Unity与Netty通信Demo是一个示例项目,展示了如何在Unity游戏引擎中利用网络库Netty进行数据通信。这个Demo提供了可直接应用于实际项目的代码,帮助开发者理解如何在Unity的C#环境中与Java后端服务器通过Netty进行...

    tcpwebsocket_java_tcp_websocket_zip_

    在IT行业中,网络通信是至关重要的部分,而TCP(传输控制协议)和WebSocket协议则是其中的两种关键技术。本文将详细解析Java环境下如何利用TCP和WebSocket实现高效、实时的网络通信,并结合提供的“tcpwebsocket”...

    netty 新NIO框架 文档

    - **Google Protocol Buffer集成**:为了满足高性能序列化的需求,Netty还集成了Google的Protocol Buffer库,进一步提升了数据处理的速度。 #### 四、入门示例详解 ##### 4.1 编写丢弃服务器 Netty提供了快速搭建...

    Netty 3.2 用户手册

    Netty框架能够有效地支持多种协议,包括但不限于HTTP、WebSocket、SSL/TLS和Google Protocol Buffers等。由于它的设计允许开发者在不牺牲性能和稳定性的情况下,轻松地实现这些协议,因此它在需要处理大数据量、高...

    netty nio 技术文档

    #### 四、Netty应用示例解析 1. **编写一个丢弃服务**:创建一个简单的服务端程序,接收到客户端的任何数据后立即丢弃。 - 初始化`EventLoopGroup`。 - 创建`ServerBootstrap`并设置参数。 - 使用`...

    NettyServer--zzz.zip

    Netty和DotNetty支持多种协议,如TCP、UDP、HTTP、WebSocket、FTP等,这使得开发者能够灵活地选择最适合项目需求的协议。双向通信意味着数据可以同时从客户端发送到服务器,以及从服务器发送回客户端,实现了全双工...

    笔记,2、Netty应用1

    1. **Netty 提供了丰富的数据格式封装**:与原生的JAVA NIO框架相比,Netty提供了对Protocol Buffer、JSON等信息格式的封装。它采用了责任链模式的编码和解码功能,使得数据在传输过程中的转换变得更加简单和高效。 ...

    Java中使用Thrift实现RPC示例代码.rar

    总结起来,这个"Java中使用Thrift实现RPC示例代码"涵盖了Thrift服务的定义、Java代码的生成、服务端与客户端的实现,以及可能的Netty集成。通过学习这个示例,开发者可以深入理解Thrift在Java环境中的工作方式,以及...

    java开源包3

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    java开源包1

    jSIP这个Java包目标是用Java实现SIP(SIP:Session Initiation Protocol)协议及SIP协议的其它扩展部 分。 Java表达式语法解析库 parboiled parboiled 是一个纯Java库提供了一种轻量级,易于使用,功能强大和优雅的PEG...

    Java Socket 实现SMTP邮件发送,支持SSL/TSL

    在本案例中,我们将关注如何使用Java Socket来实现SMTP(Simple Mail Transfer Protocol)邮件发送,并支持SSL(Secure Sockets Layer)和TLS(Transport Layer Security)安全协议。 SMTP是一种互联网标准,用于在...

    blog_project:개인적으로예제를공간입니다。 IntelliJ,Spring Boot,JAVA,TCP,Netty

    博客项目(blog_project)是一个个人空间,用于展示和学习各种技术示例,主要涉及IntelliJ IDEA、Spring Boot、Java编程语言、TCP协议以及Netty框架。这些元素构成了现代Web开发的重要组成部分,让我们逐一深入探讨...

    Multiplayer Pac-Man with RSocket-Ryland Degnan.pdf

    RSocket是一个现代的、双向的、基于TCP或WebSocket的通信协议,它支持多种交互模式,如请求-响应、发布-订阅、单向和双向流,这使得它成为构建实时多玩家游戏的理想选择。 首先,我们需要明确多玩家Pac-Man游戏的...

Global site tag (gtag.js) - Google Analytics