Netty: WebSocket应用,代码demo

简介: Netty: WebSocket应用,代码demo

WebSocket

为什么使用进阶版呢? 新的技术肯定是解决了 技术的问题


Http协议都的缺陷 :


通信只能由客户端发起,需要一种服务端能够主动推送到能力 –websocket


**websocket:**这是一种双向通信的能力 也叫做 : “全双工”


websocket是由浏览器发起的


通常我们使用 http叫做 : 短连接 性能好一点


用 websocket 叫做 : 长连接 复用性高一些


适用于不同场景


这里我们还是使用 http来链连接 只不过 连接之后就传输信息 直到断开为止


应为本质上 http 底层是 tcp 是支持实现全双工的


协议标识符 http://127.0.0.1:8080 ws://127.0.0.1:7777


GET ws://127.0.0.1:7777 HTTP/1.1
Host: 127.0.0.1
Upgrade: websocket    # 升级为ws   
Connection: Upgrade   # 此链接需要升级
Sec-WebSocket-key: client-random-string ...  # 标识加密相关信息

响应结果

HTTP/1.1 101
Upgrade: websocket
Connection: Upgrade

响应码 101 代表本次协议需要更改为websocket


连接建立后,支持文本信息及二进制信息。


Websocket实现的原理:

通过http协议进行连接的建立(握手和回答),建立连接后不再使用http,而tcp自身是支持双向通信的,所以能达到“全双工”的效果。


Websocket 应用demo

服务端代码


public class WebSocketServer {
    public static void main(String[] args) {
        //可以自定义线程的数量
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        // 默认创建的线程数量 = CPU 处理器数量 *2
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler())
                //当前连接被阻塞的时候,BACKLOG代表的事 阻塞队列的长度
                .option(ChannelOption.SO_BACKLOG, 128)
                //设置连接保持为活动状态
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new WebSocketInitialzer());
        try {
            ChannelFuture future = serverBootstrap.bind(7777).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

服务端初始化器


public class WebSocketInitialzer extends ChannelInitializer<Channel> {
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        //增加编解码器 的另一种方式
        pipeline.addLast(new HttpServerCodec());
        //    块方式写的处理器 适合处理大数据
        pipeline.addLast(new ChunkedWriteHandler());
        //聚合
        pipeline.addLast(new HttpObjectAggregator(512 * 1024));
        /*
         * 这个时候 我们需要声明我们使用的是 websocket 协议
         * netty为websocket也准备了对应处理器  设置的是访问路径
         * 这个时候我们只需要访问 ws://127.0.0.1:7777/hello 就可以了
         * 这个handler是将http协议升级为websocket  并且使用 101 作为响应码
         * */
        pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));
        pipeline.addLast(new WebSocketHandler());
    }
}

服务端处理器


通信使用的单位叫帧 frame

客户端:发送时将消息切割成多个帧

服务端:接收时,将关联的帧重新组装


/*
 * 泛型 代表的是处理数据的单位
 * TextWebSocketFrame : 文本信息帧
 * */
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame textWebSocketFrame) throws Exception {
        //可以直接调用text 拿到文本信息帧中的信息
        System.out.println("msg:" + textWebSocketFrame.text());
        Channel channel = ctx.channel();
        //我们可以使用新建一个对象 将服务端需要返回的信息放入其中 返回即可
        TextWebSocketFrame resp = new TextWebSocketFrame("hello client from websocket server");
        channel.writeAndFlush(resp);
    }
}

websocket前端编写


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    var socket;
    //    判断当前浏览器是否支持websocket
    if (!window.WebSocket) {
        alert("不支持websocket")
    } else {
        <!-- 创建websocket 连接对象-->
        socket = new WebSocket("ws://127.0.0.1:7777/hello");
        //设置开始连接的方法
        socket.onopen = function (ev) {
            var tmp = document.getElementById("respText");
            tmp.value = "连接已经开启";
        }
        //设置关闭连接的方法
        socket.onclose = function (ev) {
            var tmp = document.getElementById("respText");
            tmp.value = tmp.value + "\n" + "连接已经关闭";
        }
        //设置接收数据的方法
        socket.onmessage = function (ev) {
            var tmp = document.getElementById("respText");
            tmp.value = tmp.value + "\n" + ev.data;
        }
    }
    function send(message) {
        if (!window.socket) {
            return
        }
        /*
        * 判断socket的状态
        * connecting 正在连接 closing 正在关闭
        * closed 已经关闭或打开连接失败
        * open 连接可以 已经正常通信
        * */
        if (socket.readyState == WebSocket.OPEN) {
            socket.send(message);
        } else {
            alert("连接未开启");
        }
    }
</script>
<!--防止表单自动提交-->
<form onsubmit="return false">
    <textarea name="message" style="height: 400px;width: 400px"></textarea>
    <input type="button" value="发送" onclick="send(this.form.message.value)">
    <textarea id="respText" style="height: 400px;width: 400px"></textarea>
</form>
</body>
</html>

【客户端】


var ws = new WebSocket("ws://127.0.0.1:7777/hello");
ws.onopen = function(ev){
     ws.send("hello"); //建立连接后发送数据
}

设计一个样式

左右两个各有一个文本框,中间放一个发送按钮。

左侧文本框用来发送数据,右侧文本框用来显示数据。


演示效果

启动服务发送消息

1.png



服务器接受到的消息

2.png


小结

websocket 一般用于做可复用连接,http一般做短链接

websocket解决了http连接只能客户端发起的痛点


相关文章
|
2月前
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
340 1
|
2月前
|
前端开发 JavaScript UED
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
通过在Django项目中集成Channels和WebSocket,我们能够为前后端分离的应用添加实时通信功能,实现诸如在线聊天、实时数据更新等交互式场景。这不仅增强了应用的功能性,也提升了用户体验。随着实时Web应用的日益普及,掌握Django Channels和WebSocket的集成将为开发者开启新的可能性,推动Web应用的发展迈向更高层次的实时性和交互性。
83 1
|
3月前
|
存储 JavaScript 前端开发
webSocket+Node+Js实现在线聊天(包含所有代码)
文章介绍了如何使用WebSocket、Node.js和JavaScript实现在线聊天功能,包括完整的前端和后端代码示例。
187 0
|
2月前
|
JavaScript 前端开发 测试技术
前端全栈之路Deno篇(五):如何快速创建 WebSocket 服务端应用 + 客户端应用 - 可能是2025最佳的Websocket全栈实时应用框架
本文介绍了如何使用Deno 2.0快速构建WebSocket全栈应用,包括服务端和客户端的创建。通过一个简单的代码示例,展示了Deno在WebSocket实现中的便捷与强大,无需额外依赖,即可轻松搭建具备基本功能的WebSocket应用。Deno 2.0被认为是最佳的WebSocket全栈应用JS运行时,适合全栈开发者学习和使用。
110 7
|
1月前
|
Kubernetes Cloud Native JavaScript
为使用WebSocket构建的双向通信应用带来基于服务网格的全链路灰度
介绍如何使用为基于WebSocket的云原生应用构建全链路灰度方案。
|
2月前
|
前端开发 网络协议
netty整合websocket(完美教程)
本文是一篇完整的Netty整合WebSocket的教程,介绍了WebSocket的基本概念、使用Netty构建WebSocket服务器的步骤和代码示例,以及如何创建前端WebSocket客户端进行通信的示例。
199 2
netty整合websocket(完美教程)
|
3月前
|
JavaScript 前端开发 UED
WebSocket在Python Web开发中的革新应用:解锁实时通信的新可能
在快速发展的Web应用领域中,实时通信已成为许多现代应用不可或缺的功能。传统的HTTP请求/响应模式在处理实时数据时显得力不从心,而WebSocket技术的出现,为Python Web开发带来了革命性的变化,它允许服务器与客户端之间建立持久的连接,从而实现了数据的即时传输与交换。本文将通过问题解答的形式,深入探讨WebSocket在Python Web开发中的革新应用及其实现方法。
47 3
|
2月前
|
消息中间件 网络协议 安全
C# 一分钟浅谈:WebSocket 协议应用
【10月更文挑战第6天】在过去的一年中,我参与了一个基于 WebSocket 的实时通信系统项目,该项目不仅提升了工作效率,还改善了用户体验。本文将分享在 C# 中应用 WebSocket 协议的经验和心得,包括基础概念、C# 实现示例、常见问题及解决方案等内容,希望能为广大开发者提供参考。
119 0
|
4月前
|
人工智能 安全 Go
Golang 搭建 WebSocket 应用(八) - 完整代码
Golang 搭建 WebSocket 应用(八) - 完整代码
41 0
|
5月前
|
前端开发 网络协议 JavaScript
在Spring Boot中实现基于WebSocket的实时通信
在Spring Boot中实现基于WebSocket的实时通信