Skip to content

Commit 7ddba2a

Browse files
committed
problem: WS client doesn't parse large blocks
1 parent bbadea9 commit 7ddba2a

File tree

1 file changed

+65
-34
lines changed

1 file changed

+65
-34
lines changed

etherjar-rpc-ws/src/main/java/io/infinitape/etherjar/rpc/ws/SocketApiHandler.java

+65-34
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
package io.infinitape.etherjar.rpc.ws;
1717

1818
import com.fasterxml.jackson.core.JsonProcessingException;
19+
import io.infinitape.etherjar.rpc.RpcResponseException;
1920
import io.netty.channel.*;
2021
import io.netty.handler.codec.http.FullHttpResponse;
2122
import io.netty.handler.codec.http.websocketx.*;
2223
import io.netty.util.CharsetUtil;
2324

25+
import java.nio.charset.Charset;
2426
import java.util.ArrayList;
2527
import java.util.HashMap;
2628
import java.util.List;
@@ -47,6 +49,8 @@ public class SocketApiHandler extends SimpleChannelInboundHandler<Object> {
4749
private List<Subscription> subscriptions = new ArrayList<>();
4850
private JacksonWsConverter rpcConverter = new JacksonWsConverter();
4951

52+
private List<String> buffer = new ArrayList<>();
53+
5054
public ChannelFuture handshakeFuture() {
5155
return handshakeFuture;
5256
}
@@ -75,52 +79,79 @@ protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Except
7579
}
7680

7781
final WebSocketFrame frame = (WebSocketFrame) msg;
78-
if (frame instanceof TextWebSocketFrame) {
79-
final TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
80-
SubscriptionJson json = rpcConverter.readSubscription(textFrame.text());
81-
if (json.getSubscription() != null) {
82-
boolean consumed = false;
83-
String id = json.getSubscription();
84-
for (int i = 0; i < subscriptions.size() && !consumed; i++) {
85-
Subscription s = subscriptions.get(i);
86-
if (id.equals(s.getId())) {
87-
consumed = true;
88-
s.onReceive(json);
89-
}
90-
}
91-
if (!consumed) {
92-
System.err.println("Unknown subscription:" + id);
93-
}
94-
} else if (json.getId() != null) {
95-
subscribeLock.lock();
96-
try {
97-
Subscription s = initializing.remove(json.getId());
98-
if (s != null) {
99-
s.setId(json.getStringResult());
100-
if (json.getError() != null) {
101-
subscriptions.remove(s);
102-
s.onClose(json.extractError());
103-
}
104-
} else {
105-
System.err.println("Cannot find subscriber " + json.getId());
106-
}
107-
} finally {
108-
subscribeLock.unlock();
109-
}
82+
if (frame instanceof TextWebSocketFrame || frame instanceof ContinuationWebSocketFrame) {
83+
String textFrameContent = frame.content().toString(CharsetUtil.UTF_8);
84+
if (frame.isFinalFragment()) {
85+
String fullMessage = extractBuffer(textFrameContent);
86+
processMessage(fullMessage);
87+
} else {
88+
buffer.add(textFrameContent);
11089
}
11190
} else if (frame instanceof CloseWebSocketFrame) {
11291
ch.close();
92+
} else {
93+
System.err.println("Invalid frame: " + frame.getClass());
94+
}
95+
}
96+
97+
protected String extractBuffer(String last) {
98+
String fullMessage;
99+
if (buffer.isEmpty()) {
100+
fullMessage = last;
101+
} else {
102+
StringBuilder sb = new StringBuilder();
103+
for (String s : buffer) {
104+
sb.append(s);
105+
}
106+
buffer = new ArrayList<>();
107+
sb.append(last);
108+
fullMessage = sb.toString();
113109
}
110+
return fullMessage;
111+
}
114112

113+
public void processMessage(String message) throws RpcResponseException {
114+
SubscriptionJson json = rpcConverter.readSubscription(message);
115+
if (json.getSubscription() != null) {
116+
boolean consumed = false;
117+
String id = json.getSubscription();
118+
for (int i = 0; i < subscriptions.size() && !consumed; i++) {
119+
Subscription s = subscriptions.get(i);
120+
if (id.equals(s.getId())) {
121+
consumed = true;
122+
s.onReceive(json);
123+
}
124+
}
125+
if (!consumed) {
126+
System.err.println("Unknown subscription:" + id);
127+
}
128+
} else if (json.getId() != null) {
129+
subscribeLock.lock();
130+
try {
131+
Subscription s = initializing.remove(json.getId());
132+
if (s != null) {
133+
s.setId(json.getStringResult());
134+
if (json.getError() != null) {
135+
subscriptions.remove(s);
136+
s.onClose(json.extractError());
137+
}
138+
} else {
139+
System.err.println("Cannot find subscriber " + json.getId());
140+
}
141+
} finally {
142+
subscribeLock.unlock();
143+
}
144+
}
115145
}
116146

117147
public void stop() {
118148
subscribeLock.lock();
119149
try {
120-
for (Subscription s: subscriptions) {
150+
for (Subscription s : subscriptions) {
121151
try {
122152
s.stop(rpcConverter.getObjectMapper(), sequence.getAndIncrement());
123-
} catch (Exception e) { }
153+
} catch (Exception e) {
154+
}
124155
}
125156
} finally {
126157
subscribeLock.unlock();

0 commit comments

Comments
 (0)