【发布时间】:2021-08-29 09:55:07
【问题描述】:
我正在构建一个处理对象绘制的 WebSocket 服务器。下面是服务器类的样子:
import fmi.whiteboard.models.paths.*;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@ServerEndpoint(value = "/whiteboard",
encoders = {DrawingEncoder.class, ShapeEncoder.class, PathEncoder.class},
decoders = {DrawingDecoder.class, ShapeDecoder.class, PathDecoder.class})
public class WhiteboardServer {
private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());
@OnOpen
public void onOpen(Session peer) {
peers.add(peer);
}
@OnClose
public void onClose(Session peer) {
peers.remove(peer);
}
@OnMessage
public void broadcastShape(Drawing drawing, Session session) throws IOException, EncodeException {
for (Session peer : peers) {
if (!peer.equals(session)) {
peer.getAsyncRemote().sendObject(drawing);
}
}
}
}
下面是处理绘图的 ReactJS 组件的样子:
export default function Whiteboard() {
const canvas = useRef(null);
const ws = useMemo(() => {
const socket = new WebSocket("ws://localhost:8080/backend_war/whiteboard");
socket.binaryType = "arraybuffer";
return socket;
}, []);
useEffect(() => {
ws.onmessage = (evt: MessageEvent) => {
const data: SocketResponse = JSON.parse(evt.data);
if (data && data.shapes) {
canvas?.current?.loadPaths(data.shapes);
}
};
ws.onerror= (err) => console.log(err);
}, [ws]);
const onDraw = (message: CanvasPath[]) => {
ws.send(JSON.stringify({ shapes: message }));
};
return (
<>
<ReactSketchCanvas
ref={canvas}
style={styles}
onUpdate={(paths) => setPaths(paths)}
strokeWidth={4}
strokeColor="red"
/>
</>
);
}
该应用程序可以正常工作 2-3 秒,但一旦我开始绘制更多形状,套接字服务器就会崩溃,ConcurrentModificationException 与 for (Session peer : peers) 在线。
如果有任何帮助,我将使用 Java 11 和 Tomcat 10 作为服务器。
【问题讨论】: