栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Netty学习-简易的通信

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Netty学习-简易的通信

netty

因为大创项目需要一个类似于QQ的聊天功能的需求,因此学习了netty与websocket。现在记录下第一次简易的实时聊天

java后端 pom.xml

只是引入了一个netty的包



    4.0.0

    org.example
    netty-learn
    1.0-SNAPSHOT

    
        
        
            io.netty
            netty-all
            4.1.79.Final
        
    
    
        11
        11
    

后端服务器 WebSocketServer
package org.example;

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 WebSocketServer {

    public static void main(String[] args) {
        // 创建主线程池
        NioEventLoopGroup mainGroup = new NioEventLoopGroup();
        // 创建从线程池
        NioEventLoopGroup subGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap server = new ServerBootstrap();
            // 分组
            server.group(mainGroup, subGroup)
                    // 使用 NioServerSocketChannel 作为数据通道
                    .channel(NioServerSocketChannel.class)
                    // 添加 websocket 处理器
                    .childHandler(new WebSocketServerInitialzer());
            ChannelFuture future = server.bind(8088).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            // 关闭资源
            mainGroup.shutdownGracefully();
            subGroup.shutdownGracefully();
        }
    }
}
WebSocket
package org.example;

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;

public class WebSocketServerInitialzer extends ChannelInitializer {
    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        // 集成了很多的 handler 的流水线
        ChannelPipeline pipeline = channel.pipeline();

        // http 的编码与解码器
        pipeline.addLast(new HttpServerCodec());

        // 数据过大处理
        pipeline.addLast(new ChunkedWriteHandler());

        // 消息聚合
        pipeline.addLast(new HttpObjectAggregator(1024*64));

        // 协议 前端需要写这个一致
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        // 添加聊天处理器
        pipeline.addLast(new ChatHandler());
    }
}

ChatHandler
package org.example;

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;



public class ChatHandler extends SimpleChannelInboundHandler {

    
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame msg) throws Exception {
        String content = msg.text();
        System.out.println("content = " + content);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        // 数据响应前端
        clients.writeAndFlush(
                new TextWebSocketFrame(
                        "用户" + channelHandlerContext.channel().id().asShortText() + "在" + dateFormat.format(new Date()) + "说" + content
                )
        );
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("用户上线" + ctx.channel().id().asShortText());
        clients.add(ctx.channel());
        ctx.channel().writeAndFlush(new TextWebSocketFrame(ctx.channel().id().asShortText()));
    }


    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户断开链接" + ctx.channel().id().asShortText());
        clients.remove(ctx.channel());
    }
}

vue 前端

一个简单的vue3脚手架

编写配置类configs
// 这是configs 下的index.js
const BASE_URL = '192.168.1.5'
const WS_PORT = '8088'
const WS_ADDRESS = `ws://${BASE_URL}:${WS_PORT}/ws` // 这个ws 就是后端写的那个
export { WS_ADDRESS }
编写 hooks 的 index.js
// 这个是hooks 的 index.js
import userWebSocket from './websocket'

export { userWebSocket }

编写 hooks 的 websocket.js
import { WS_ADDRESS } from '../configs/index.js'
function userWebSocket(handleMessage) {
  const ws = new WebSocket(WS_ADDRESS)

  const init = () => {
    bindEvent()
  }

  function bindEvent() {
    ws.addEventListener('open', handleOpen, false)
    ws.addEventListener('close', handleClose, false)
    ws.addEventListener('error', handleError, false)
    ws.addEventListener('message', handleMessage, false)
  }

  function handleOpen(e) {
    console.log('socket 连接成功', e)
  }
  function handleClose(e) {
    console.log('socket 连接关闭 close', e)
  }
  function handleError(e) {
    console.log('socket 连接错误', e)
  }

  init()

  return ws
}
export default userWebSocket

编写聊天组件chat.vue



将组件挂到APP.vue 上就可以了最后运行

最后效果

现在仅是学习阶段,有点潦草,一起学习,勿喷

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1040685.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号