netty编程之实现websocket客户端并发送二进制消息

写在前面

源码

本文看下netty如何实现websocket客户端并发送二进制消息。

ws的server端参考这篇文章

1:正文

抽象类AbstractWebsocketClient定义了发送二进制数据的方法:

java 复制代码
public abstract class AbstractWebsocketClient implements Closeable {

    /**
     * 发送消息.<br>
     *
     * @param message 发送文本
     */
    public void send(String message) throws MyException {
        Channel channel = getChannel();
        if (channel != null) {
            channel.writeAndFlush(new TextWebSocketFrame(message));
            return;
        }
        throw new MyException("连接已经关闭");
    }

    /**
     * 发送消息.<br>
     *
     * @param message 二进制消息
     */
    public void sendBinary(byte[] message) throws MyException {
//        System.out.println("AbstractWebsocketClient.sendBinary: 发送二进制数据:" + message.length);
        Channel channel = getChannel();
        if (channel != null) {
//            channel.writeAndFlush(new TextWebSocketFrame(message));
            ByteBuf byteBuf = Unpooled.directBuffer(message.length);
            byteBuf.writeBytes(message);
//            channel.writeAndFlush(new BinaryWebSocketFrame(message));
            channel.writeAndFlush(new BinaryWebSocketFrame(byteBuf));
            return;
        }
        throw new MyException("连接已经关闭");
    }
}    

方法sendBinary就是发送二进制数据,接着测试:

java 复制代码
package com.dahuyou.netty.ws.client;

//import lombok.extern.slf4j.Slf4j;

import org.omg.PortableServer.THREAD_POLICY_ID;

import java.io.File;
import java.io.FileInputStream;
import java.net.URISyntaxException;

//@Slf4j
public class Test {

    public static void main(String[] args) throws Exception {
        WebsocketClient websocketClient = new WebsocketClient("ws://127.0.0.1:9898/chat");
//        try (WebsocketClient websocketClient = new WebsocketClient("ws://127.0.0.1:9898/chat")) {
        // 连接
        websocketClient.connect();
        // 发送消息
//            websocketClient.send("xxxxxxxxxxxxxxxxx");


//            String fileName=FunasrWsClient.wavPath;
//        String fileName = "d:\\test\\ttsmaker-file-2024-9-19-18-51-21.wav";
        String fileName = "d:\\test\\ttsmaker-file-2024-9-29-11-28-50.wav";
        String suffix = fileName.split("\\.")[fileName.split("\\.").length - 1];
//            sendJson(mode, strChunkSize, chunkInterval, wavName, true,suffix);
        File file = new File(fileName);
        int sendChunkSize = 1920;
        int chunkSize = sendChunkSize;
        byte[] bytes = new byte[chunkSize];
        int readSize = 0;
        try (FileInputStream fis = new FileInputStream(file)) {
//                if (FunasrWsClient.wavPath.endsWith(".wav")) {
//                    fis.read(bytes, 0, 44); //skip first 44 wav header
//                }
            fis.read(bytes, 0, 44); //skip first 44 wav header

            readSize = fis.read(bytes, 0, chunkSize);
            while (readSize > 0) {
                // send when it is chunk size
                if (readSize == chunkSize) {
//                        send(bytes); // send buf to server
                    websocketClient.sendBinary(bytes);
                } else {
                    // send when at last or not is chunk size
                    byte[] tmpBytes = new byte[readSize];
                    for (int i = 0; i < readSize; i++) {
                        tmpBytes[i] = bytes[i];
                    }
//                        send(tmpBytes);
                    websocketClient.sendBinary(tmpBytes);
                }
                readSize = fis.read(bytes, 0, chunkSize);
                Thread.sleep(200);
            }

            // 发送空白音
//            while (readSize > 0) {
            for (;;) {
                websocketClient.sendBinary(new byte[chunkSize]);
                Thread.sleep(200);
            }

//            Thread.sleep(10000000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 阻塞一下,否则这里客户端会调用close方法
        Thread.sleep(10);
//        } catch (URISyntaxException | MyException | InterruptedException e) {
            log.error("发生异常,原因:{}", e.getMessage(), e);
//            System.out.println("发生异常,原因:{}" +  e.getMessage() + " e:" + e);
//        }

    }
}

ttsmaker-file-2024-9-29-11-28-50.wav

我这里是通过读取一个音频文件实现二进制数据读取的,实际情况下你可以根据具体情况来修改即可。

运行:

你的ws server端write回什么内容这里就会输出什么内容,所以不必纠结我这里输出的信息,能通即可!!!

写在后面

文章只给出了关键点,具体的大家还是看源码哈!

参考文章列表

【netty客户端】通过netty实现封装websocket客户端

netty编程之基于websocket接收二进制数据

相关推荐
GitLqr15 小时前
玩转 WebSocket:从原理到 Flutter 实战
websocket·网络协议·flutter
乱七八糟的屋子2 天前
Poco C++高级实战教程:线程池+日志系统+加密算法+WebSocket长连接
c++·websocket·加密解密·#poco·#c++高级开发
宠友信息4 天前
MySQL复合索引与Druid优化仿小红书源码个人主页查询链路
数据库·spring boot·websocket·mysql·uni-app
程序猿乐锅4 天前
【苍穹外卖 day10|Spring Task、WebSocket 与来单提醒、催单铃声实现】
java·websocket·spring
宠友信息5 天前
消息撤回与已读状态如何在即时通讯源码中统一管理
java·spring boot·websocket·mysql·uni-app
paopaokaka_luck7 天前
基于Springboot3+vue3的旅游景区点评系统(AI审核、webSocket聊天、协同过滤算法、Echarts图形化分析)
websocket·网络协议·旅游
熬夜苦读学习7 天前
基于websocket的多用户五子棋网页游戏
linux·服务器·网络·websocket·网络协议·游戏·五子棋
米尔的可达鸭7 天前
深入操作系统 Socket 底层:EPOLLOUT 可写事件管理 + 非阻塞异步
开发语言·网络·数据结构·经验分享·websocket·网络协议
米尔的可达鸭8 天前
深入操作系统 Socket 底层:套接字控制块、FD映射、阻塞IO核心完整实现
arm开发·数据结构·websocket·网络协议·算法·架构·安全架构
永久鳕11 天前
WebSocket 连接成功但行情不更新,应该先查哪几个状态?
网络·websocket·网络协议