Skip to content

Commit 6a0524b

Browse files
committed
(feat:model/cosyvoice):use new protocol to build websocket connection
1 parent e06dd85 commit 6a0524b

File tree

4 files changed

+867
-0
lines changed

4 files changed

+867
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.alibaba.dashscope.audio.protocol;
2+
3+
import java.nio.ByteBuffer;
4+
import okhttp3.WebSocket;
5+
6+
/** @author songsong.shao */
7+
public interface AudioWebsocketCallback {
8+
9+
void onOpen();
10+
11+
void onMessage(WebSocket webSocket, String text);
12+
13+
void onMessage(WebSocket webSocket, ByteBuffer text);
14+
15+
void onError(WebSocket webSocket, Throwable t);
16+
17+
void onClose(int code, String reason);
18+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package com.alibaba.dashscope.audio.protocol;
2+
3+
import com.alibaba.dashscope.exception.NoApiKeyException;
4+
import com.alibaba.dashscope.protocol.DashScopeHeaders;
5+
import com.alibaba.dashscope.protocol.okhttp.OkHttpClientFactory;
6+
import com.alibaba.dashscope.utils.ApiKey;
7+
import com.alibaba.dashscope.utils.Constants;
8+
import java.util.Map;
9+
import java.util.concurrent.CountDownLatch;
10+
import java.util.concurrent.TimeUnit;
11+
import java.util.concurrent.atomic.AtomicBoolean;
12+
import java.util.concurrent.atomic.AtomicReference;
13+
import lombok.extern.slf4j.Slf4j;
14+
import okhttp3.*;
15+
import okio.ByteString;
16+
17+
/** @author songsong.shao */
18+
@Slf4j
19+
public class AudioWebsocketRequest extends WebSocketListener {
20+
21+
private OkHttpClient client;
22+
private WebSocket websocktetClient;
23+
private AtomicBoolean isOpen = new AtomicBoolean(false);
24+
private AtomicReference<CountDownLatch> connectLatch = new AtomicReference<>(null);
25+
private AtomicBoolean isClosed = new AtomicBoolean(false);
26+
private AudioWebsocketCallback callback;
27+
private Integer connectTimeout = 5000;
28+
29+
public boolean isOpen() {
30+
return isOpen.get();
31+
}
32+
33+
public boolean isClosed() {
34+
return isClosed.get();
35+
}
36+
37+
public void checkStatus() {
38+
if (this.isClosed.get()) {
39+
throw new RuntimeException("Websocket is already closed!");
40+
}
41+
}
42+
43+
public void connect(
44+
String apiKey,
45+
String workspace,
46+
Map<String, String> customHeaders,
47+
String baseWebSocketUrl,
48+
AudioWebsocketCallback callback)
49+
throws NoApiKeyException, InterruptedException, RuntimeException {
50+
Request request =
51+
buildConnectionRequest(
52+
ApiKey.getApiKey(apiKey), false, workspace, customHeaders, baseWebSocketUrl);
53+
this.callback = callback;
54+
client = OkHttpClientFactory.getOkHttpClient();
55+
websocktetClient = client.newWebSocket(request, this);
56+
connectLatch.set(new CountDownLatch(1));
57+
boolean result = connectLatch.get().await(connectTimeout, TimeUnit.MILLISECONDS);
58+
if (!result) {
59+
throw new RuntimeException(
60+
"TimeoutError: waiting for websocket connect more than" + connectTimeout + " ms.");
61+
}
62+
}
63+
64+
private Request buildConnectionRequest(
65+
String apiKey,
66+
boolean isSecurityCheck,
67+
String workspace,
68+
Map<String, String> customHeaders,
69+
String baseWebSocketUrl)
70+
throws NoApiKeyException {
71+
// build the request builder.
72+
Request.Builder bd = new Request.Builder();
73+
bd.headers(
74+
Headers.of(
75+
DashScopeHeaders.buildWebSocketHeaders(
76+
apiKey, isSecurityCheck, workspace, customHeaders)));
77+
String url = Constants.baseWebsocketApiUrl;
78+
if (baseWebSocketUrl != null) {
79+
url = baseWebSocketUrl;
80+
}
81+
Request request = bd.url(url).build();
82+
return request;
83+
}
84+
85+
private void sendMessage(String message, boolean enableLog) {
86+
checkStatus();
87+
if (enableLog == true) {
88+
log.debug("send message: " + message);
89+
}
90+
Boolean isOk = websocktetClient.send(message);
91+
}
92+
93+
public void close() {
94+
this.close(1000, "bye");
95+
}
96+
97+
public void close(int code, String reason) {
98+
checkStatus();
99+
websocktetClient.close(code, reason);
100+
isClosed.set(true);
101+
}
102+
103+
public void sendTextMessage(String message) {
104+
checkStatus();
105+
this.sendMessage(message, true);
106+
}
107+
108+
public void sendBinaryMessage(ByteString rawData) {
109+
checkStatus();
110+
websocktetClient.send(rawData);
111+
}
112+
113+
@Override
114+
public void onOpen(WebSocket webSocket, Response response) {
115+
isOpen.set(true);
116+
connectLatch.get().countDown();
117+
log.debug("WebSocket opened");
118+
callback.onOpen();
119+
}
120+
121+
@Override
122+
public void onMessage(WebSocket webSocket, String text) {
123+
callback.onMessage(webSocket, text);
124+
}
125+
126+
@Override
127+
public void onMessage(WebSocket webSocket, ByteString bytes) {
128+
log.debug("Received binary message");
129+
callback.onMessage(webSocket, bytes.asByteBuffer());
130+
}
131+
132+
@Override
133+
public void onClosed(WebSocket webSocket, int code, String reason) {
134+
isOpen.set(false);
135+
isClosed.set(true);
136+
connectLatch.get().countDown();
137+
log.debug("WebSocket closed");
138+
callback.onClose(code, reason);
139+
}
140+
141+
@Override
142+
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
143+
log.error("WebSocket failed: " + t.getMessage());
144+
if (connectLatch.get() != null) {
145+
connectLatch.get().countDown();
146+
}
147+
if (callback != null) {
148+
callback.onError(webSocket, t);
149+
} else {
150+
throw new RuntimeException(t);
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)