写在前面
源码。
本文看下netty如何实现websocket客户端并发送二进制消息。
ws的server端参考这篇文章。
1:正文
抽象类AbstractWebsocketClient定义了发送二进制数据的方法:
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就是发送二进制数据,接着测试:
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 headerreadSize = fis.read(bytes, 0, chunkSize);while (readSize > 0) {// send when it is chunk sizeif (readSize == chunkSize) {
// send(bytes); // send buf to serverwebsocketClient.sendBinary(bytes);} else {// send when at last or not is chunk sizebyte[] 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接收二进制数据。