写在前面
源码。
本文看下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 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接收二进制数据。