前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty-WebSocket 网络聊天demo教程

Netty-WebSocket 网络聊天demo教程

作者头像
名字是乱打的
发布2021-12-22 15:41:36
4380
发布2021-12-22 15:41:36
举报
文章被收录于专栏:软件工程软件工程

毕设需求,调研一下,新手来说任何项目都是从研究demo开始的(至少我这个菜鸡就这样,只能先研究研究再开始做自己的项目),这里提供了一个我最开始的demo,提供借鉴

代码语言:javascript
复制
<!--先来一下netty的 maven仓库配置需求-->
 <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.25.Final</version>
        </dependency>
服务端搭建

服务器三个代码块基本是层层构建,像盖房子一样从低向上一样 部分代码是常规配置,大家注意看注释哦

1.1服务器基础配置
代码语言:javascript
复制
package com.zyh.future.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class WebSocketNettyServer {
    public static void main(String[] args){  
        //创建netty的主从两个线程池
        NioEventLoopGroup mainGrp = new NioEventLoopGroup();//主线程池
        NioEventLoopGroup subGrp = new NioEventLoopGroup();//从线程池

        try {
            //创建Netty服务器启动对象
            ServerBootstrap serverBootstrap = new ServerBootstrap();

            //初始化服务器启动对象
            serverBootstrap
                    //为netty服务器指定和配备主从线程池
                    .group(mainGrp,subGrp)
                    //指定netty通道类型
                    .channel(NioServerSocketChannel.class)
                    //指定通道初始化器用来加载当channel收到消息后
                    //如何进行业务处理
                    .childHandler(new WebSocketChannelInitializer());

            //绑定服务器端口, 以同步的方式启动服务器
            ChannelFuture channelFuture = serverBootstrap.bind(9090).sync();
            //等待服务器关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //使用优雅的方式关闭服务器
            //主要是关闭两个线程池
            mainGrp.shutdownGracefully();
            subGrp.shutdownGracefully();
        }


    }
}
2.2服务器初始化配置
代码语言:javascript
复制
package com.zyh.future.server;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * 功能描述: 通道初始化器器
 * 用来加载通道处理器(channelhandler)
 * @Author: Zyh
 * @Date: 2020/1/22 20:31
 */
public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    //初始化通道
    //在这个方法中加载对应的ChannelHandler
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        /* 固定写法部分*/
        //获取管道,将一个个ChannelHandler添加到管道中
        ChannelPipeline channelPipeline = socketChannel.pipeline();
        //可以将channelpipeline理解为拦截器
        //当我们的socketChannel数据进来时候会依次调用我们的ChannelHandler

        //添加一个http的编解码器
        channelPipeline.addLast(new HttpServerCodec());
        //添加大数据流支持
        channelPipeline.addLast(new ChunkedWriteHandler());
        //添加聚合器 ,可以将我们的httpmaessage聚合成Fullhttprequest/respond ---想拿到请求和响应就要添加聚合器
        channelPipeline.addLast(new HttpObjectAggregator(1024*24));//指定缓存大小
        /* 固定写法部分*/

        //指定接收请求的路由
        //指定必须使用ws为结尾的url才能访问
        channelPipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        //添加自定义的handler进行业务处理
        channelPipeline.addLast(new ChatHandler());


    }
}
3.3 服务器业务处理
代码语言:javascript
复制
package com.zyh.future.server;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;
import java.util.Date;


//extends SimpleChannelInboundHandler<TextWebSocketFrame> 使我们接收到的消息会封装到一个TextWebSocketFrame中
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    //用来保存所有的客户端连接
    private static ChannelGroup clients=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    //创建一个时间生成器
    private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd hh:MM");

    @Override //该方面当接收到数据时候会自动调用
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        String text=msg.text();
        System.out.println("接收到的消息为: "+text);

        //遍历clients(所有客户端,群发)
        for (Channel client:clients){
            //发送消息并刷新通道
            client.writeAndFlush(new TextWebSocketFrame(sdf.format(new Date())+": "+text));
        }
    }

    @Override   //当有新的客户端接入到服务器时候会自动调用该方法
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        clients.add(ctx.channel());//将新的连接加入channel中
    }
}
客户端搭建

最简单的demo级别,主要大家可以简单清晰的看出来数据的传输和响应

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>在线聊天室</title>
</head>
<body>
    <input type="text" id="message">
    <input type="button" value="发送消息" onclick="sendMessage()">
    </br>
    接收到的消息为:
    </br>
    <p id="server_message" style="background-color: #aaaaaa"></p>


    <script>
    //判断当前浏览器是否支持websocket (H5才支持)
        var  websocket=null;
        if (window.WebSocket){
            websocket=new WebSocket("ws://127.0.0.1:9090/ws");//前面的ws是协议,后面的ws是我们指定了接收的为ws结尾的路由
            websocket.onopen=function () {
                console.log("建立连接");
            }
            websocket.onclose=function () {
                console.log("断开连接");
            }
            websocket.onmessage=function (e) {
                console.log("接收到服务器的数据为: "+e.data);
                var server_messsage=document.getElementById("server_message");
                server_messsage.innerHTML+=e.data+"</br>";
            }
        }else {
            alert("当前浏览器不支持websocket");
        }

        function sendMessage() {
            var  message=document.getElementById("message");
            websocket.send(message.value);
        }
    </script>
</body>
</html>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 服务端搭建
    • 1.1服务器基础配置
      • 2.2服务器初始化配置
        • 3.3 服务器业务处理
        • 客户端搭建
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档