【发布时间】:2020-06-16 07:36:11
【问题描述】:
我正在尝试创建类似 node-websockify 的东西,它基本上是一个简单的代理服务器,用于将数据从 novnc 服务器传输到 novnc 客户端,我正在使用提到的方法 here
我在向远程客户端发送 ByteBuffer 时发生了奇怪的错误。 如前所述,客户端是 noVNC 客户端,node-websockify 和 tightvnc 完美运行
import org.eclipse.jetty.websocket.server.WebSocketHandler;
org.eclipse.jetty.server.Server serverr = new org.eclipse.jetty.server.Server(8090);
WebSocketHandler wsh = new WebSockify();
serverr.setHandler(wsh);
serverr.start();
serverr.join();
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.api.extensions.Frame;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.server.WebSocketHandler;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebSocket
public class WebSockify extends WebSocketHandler {
private static String authorizationHeader = "";
Socket vncSocket;
int vncPort = 5900;
String vncPassword = "1234560";
@Override
public void configure(WebSocketServletFactory webSocketServletFactory) {
webSocketServletFactory.register(WebSockify.class);
}
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.out.println("Received handle " + target);
try {
if (this.getWebSocketFactory().isUpgradeRequest(request, response)) {
System.out.println("Adding header");
response.addHeader("Sec-WebSocket-Protocol", "binary");
if (this.getWebSocketFactory().acceptWebSocket(request, response)) {
System.out.println("websocket accepted");
baseRequest.setHandled(true);
return;
}
System.out.println("websocket not accepted");
if (response.isCommitted()) {
System.out.println("response commited.");
return;
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
} finally {
super.handle(target, baseRequest, request, response);
}
}
@OnWebSocketConnect
public void onConnect(final Session session) throws IOException, InterruptedException {
System.out.println("Connect: " + session.getRemoteAddress().getAddress());
System.out.println(session.getUpgradeRequest().getRequestURI());
System.out.println("session open ? " + session.isOpen());
vncSocket = new Socket("127.0.0.1", vncPort);
Thread readThread = new Thread(new Runnable() {
public void run() {
try {
System.out.println("session open ? " + session.isOpen());
byte[] b = new byte[1500];
int readBytes;
while (true) {
readBytes = vncSocket.getInputStream().read(b);
System.out.println("session open ? " + session.isOpen());
System.out.println("read bytes " + readBytes + ", " + new String(b));
if (readBytes == -1) {
break;
}
if (readBytes > 0) {
System.out.println("session open ? " + session.isOpen());
ByteBuffer bb = ByteBuffer.wrap(b, 0, readBytes);
session.getRemote().sendBytes(bb);
}
}
} catch (IOException e) {
e.printStackTrace();
System.err.println(e);
}
}
});
readThread.start();
}
@OnWebSocketFrame
public void onFrame(Frame f) throws IOException {
System.out.printf("Frame: %d\n", f.getPayloadLength());
byte[] data = new byte[f.getPayloadLength()];
f.getPayload().get(data);
vncSocket.getOutputStream().write(data);
}
@OnWebSocketError
public void onError(Throwable cause) {
System.err.println(cause.getMessage());
}
}
错误和控制台输出是
会话打开?真的
线程“Thread-8”org.eclipse.jetty.websocket.api.WebSocketException 中的异常:RemoteEndpoint 不可用,当前状态 [CLOSED],期待 [OPEN 或 CONNECTED] 在 org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:308) 在 com.hossein.main.WebSockify$1.run(WebSockify.java:91) 在 java.lang.Thread.run(Unknown Source)
看起来 session.open() 返回 true 但下一行 session.getRemote().sendBytes() 导致错误。
你能帮我找出原因吗?
发现了一些东西,当我在线程内处理会话时会出现问题,我的意思是如果我不创建新线程 session.getRemote().sendBytes() 工作正常。
【问题讨论】: