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接收二进制数据

相关推荐
独断万古他化8 分钟前
【Java 实战项目】多用户网页版聊天室:消息传输模块 —— 基于 WebSocket 实现实时通信
java·spring boot·后端·websocket·ajax·mybatis
带娃的IT创业者5 小时前
WeClaw_41_桌面端与PWA文件双向传输:WebSocket与HTTP混合协议设计
websocket·网络协议·http·文件传输·pwa
liwulin05061 天前
【ESP32-S3】WiFi 网页遥控 + WebSocket 实时控制编码电机+ 实时数据显示 + 急停 + 速度滑块
网络·websocket·网络协议
哆啦code梦2 天前
SSE与WebSocket:实时通信选型指南与实现示例
websocket·sse·ws·wss
weixin_425023002 天前
【Spring Boot 2.7 整合 WebSocket 完整实战】鉴权拦截+在线用户管理+定向消息推送
spring boot·后端·websocket
honor_zhang2 天前
Vue3使用@vueuse/core集成Websocket实战及携带身份信息的3种方式
websocket·网络协议·身份验证
独断万古他化2 天前
【Java 实战项目】多用户网页版聊天室:项目总览与用户 & 好友管理模块实现
java·spring boot·后端·websocket·mybatis
英俊潇洒美少年2 天前
前端六种通信 API
网络·websocket·网络协议
weixin_425023002 天前
Spring Boot 2.7 + JDK 8 实现 WebSocket 集群分布式部署(基于 Redis Pub/Sub 方案)
java·spring boot·websocket
ETA83 天前
面试官问SSE和WebSocket的区别?看这篇就够了(含心跳机制详解)
websocket·网络协议