一起学netty(17)netty实现websocket协议

weblog 1164 0 0

Websocket协议和http协议的关系

websocket是基于TCP的一个应用协议,与HTTP协议的关联之处在于websocket的握手数据被HTTP服务器当作HTTP包来处理,主要通过Update request HTTP包建立起连接,之后的通信全部使用websocket自己的协议,就和http没啥关系了。有兴趣的同学可以多了解一下websocket协议报文的详细信息。

Netty实现websocket协议

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class NettyServerWebsocker {
    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup boot = new NioEventLoopGroup(1);
        NioEventLoopGroup work = new NioEventLoopGroup(8);
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boot,work)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        // 建立连接时需要http协议的支持
                        pipeline.addLast(new HttpServerCodec());
                        // 以块的方式来写的处理器
                        pipeline.addLast(new ChunkedWriteHandler());
                        //netty是基于分段请求的,HttpObjectAggregator的作用是将请求分段再聚合,参数是聚合字节的最大长度
                        pipeline.addLast(new HttpObjectAggregator(1024*64));
                        //这个是websocket的handler,是netty提供的,也可以自定义,建议就用默认的
                        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

                        // 消息处理器
                        pipeline.addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame text) throws Exception {
                                System.out.println(text.text());
                                channelHandlerContext.writeAndFlush(new TextWebSocketFrame("我收到你的消息了"+text.text()));
                                channelHandlerContext.fireChannelActive();
                            }
                        });
                    }
                });
        // 绑定端口
        ChannelFuture bind = bootstrap.bind(8678).sync();
        bind.channel().closeFuture().sync();
    }
}

websocket数据包的类型有四种,TextWebSocketFrame(文本消息)、BinaryWebSocketFrame(二进制消息)、PongWebSocketFrame(PING存活检测消息)、CloseWebSocketFrame(关闭指令消息)。

上述代码只能接收TextWebSocketFrame文本类型的消息,如果需要接收其他类型的消息可以继承ChannelInboundHandlerAdapter类在channelRead方法中判断。

客户端(js代码)

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>websocket</title>
</head>
<body>
<!--  网页控件元素,类似按钮/图片/文章什么的都写在这里  -->
<input type = "text" id ="v">
<input type = "button" id = "b" onclick="send()" value="send">
<div id ="text">
</div>
</body>
<script>

	let ws = new WebSocket("ws://localhost:8678/ws");
	 ws.onopen = function (event) {
		 console.log("Send Text WS was opened.");
		 ws.send("hello");
	 };
	 ws.onmessage = function (event) {
		 console.log("response text msg: " + event.data);
		 document.getElementById("text").innerHTML=event.data;
	 };
	 ws.onerror = function (event) {
		 console.log("Send Text fired an error");
	 };
	 ws.onclose = function (event) {
		 console.log("WebSocket instance closed.");
	 };
	 function send(){
		 var v = document.getElementById("v").value;
		 ws.send(v);
	 }
</script>
</html>

猜你喜欢
official 1201 什么是网络?网络就是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。有了网络才能不同设备、不同操作系统、不同软件之间的数据交换。我们常说的tcp和udp是操作系
official 1450   基于javanio+netty+websocket+protobuf+javascript等技术前后端高性能时数据传输的demo模型。  github地址:https
mqtt协议 1603 mqtt报文解析,参考:http://www.jiajiajia.club/blog/artical/kdv1qvpfgbh4/514  根据mqtt的定义,剩余长度字段是可变的,最少用
official 1247 之前的文章介绍了protobuf的概念参考:http://www.jiajiajia.club/blog/artical/351psy9r6l0g/464以及protobuf的编码方式参考:http://www.jiajiajia.club/blog/artical/5puo1goygd3o/463proto文件准备Animal.protosyntax="proto3";import"Dog.pr
official 1036 、epoll等各种多路复用器的出,我们通过原生的nio已经可以写出些高性能的程序。但是深入分析,我们还是可以从中找出很多问题:1.原生的nio服务端程序需要我们自己去解决客户端的连接、客户端收发数据,异常等问
official 1452 之前的文章中提到过,单线程的nio模型任然有定缺点。在上节《netty(7)netty的线程模型》中也提到,netty的出,封装了nio复杂的代码,并且介入多线程来处理事件,最大限度的提
框架 8223 上次我们说了spring集成websocketwebsocket通讯集成配置连接:http://www.jiajiajia.club/weblog/blog/artical/128下面来模拟
official 1285 在上节《netty(6)》的文章中,简要说明了用nio原生代码写程序的些不足和问题,以及netty在nio的基础上大致做了那些工作。其中提到点就是当活跃客户端的数量太多,单线程处理时所带
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。